mod helpers;
use helpers::{create_and_drop, create_and_drop_with_config};
use persy::Config;
use persy::SegmentError;
use persy::TxStrategy;
#[test]
fn test_insert_read_commit_record() {
create_and_drop("irc", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let bytes = String::from("something").into_bytes();
let id = tx.insert("test", &bytes).unwrap();
let read_opt = tx.read("test", &id).unwrap();
assert_eq!(read_opt, Some(bytes));
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let bytes = String::from("something").into_bytes();
let read_after = persy.read("test", &id).unwrap();
assert_eq!(read_after, Some(bytes));
});
}
#[test]
fn test_insert_update_record() {
create_and_drop("iru", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let rec_data: String = "something".into();
let bytes = rec_data.into_bytes();
let id = tx.insert("test", &bytes).unwrap();
let read_opt = tx.read("test", &id).unwrap();
assert_eq!(read_opt, Some(bytes));
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let rec_1: String = "newthing".into();
let bytes_1 = rec_1.into_bytes();
let mut tx1 = persy.begin().unwrap();
tx1.update("test", &id, &bytes_1).unwrap();
let read_after = tx1.read("test", &id).unwrap();
assert_eq!(read_after, Some(bytes_1));
let finalizer = tx1.prepare().unwrap();
finalizer.commit().unwrap();
});
}
#[test]
fn test_insert_delete_record() {
create_and_drop("ird", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let rec_data: String = "something".into();
let bytes = rec_data.into_bytes();
let id = tx.insert("test", &bytes).unwrap();
let read_opt = tx.read("test", &id).unwrap();
assert_eq!(read_opt, Some(bytes));
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let mut tx1 = persy.begin().unwrap();
tx1.delete("test", &id).unwrap();
let read_after = tx1.read("test", &id).unwrap();
assert_eq!(read_after, None);
let finalizer = tx1.prepare().unwrap();
finalizer.commit().unwrap();
});
}
#[test]
fn test_insert_scan() {
create_and_drop("irs", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let rec_data: String = "something".into();
let bytes = rec_data.into_bytes();
tx.insert("test", &bytes).unwrap();
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let iter = persy.scan("test").unwrap().into_iter();
assert_eq!(iter.count(), 1);
let (_, content) = persy.scan("test").unwrap().into_iter().next().unwrap();
assert_eq!(bytes, content);
});
}
#[test]
fn test_insert_update_same_tx() {
create_and_drop("ius", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let bytes = String::from("something").into_bytes();
let id = tx.insert("test", &bytes).unwrap();
let read_opt = tx.read("test", &id).unwrap();
assert_eq!(read_opt, Some(bytes));
let bytes = String::from("data1").into_bytes();
tx.update("test", &id, &bytes).unwrap();
let read_opt = tx.read("test", &id).unwrap();
assert_eq!(read_opt, Some(bytes));
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let read_after = persy.read("test", &id).unwrap();
let bytes = String::from("data1").into_bytes();
assert_eq!(read_after, Some(bytes));
});
}
#[test]
fn test_double_update_same_tx() {
create_and_drop("iuus", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let bytes = String::from("something").into_bytes();
let id = tx.insert("test", &bytes).unwrap();
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let mut tx = persy.begin().unwrap();
let bytes = String::from("first").into_bytes();
tx.update("test", &id, &bytes).unwrap();
let bytes = String::from("second").into_bytes();
tx.update("test", &id, &bytes).unwrap();
let read_opt = tx.read("test", &id).unwrap();
assert_eq!(read_opt, Some(bytes));
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let read_after = persy.read("test", &id).unwrap();
let bytes = String::from("second").into_bytes();
assert_eq!(read_after, Some(bytes));
});
}
#[test]
fn test_insert_update_delete_same_tx() {
create_and_drop("iuds", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let bytes = String::from("something").into_bytes();
let id = tx.insert("test", &bytes).unwrap();
let bytes = String::from("first").into_bytes();
tx.update("test", &id, &bytes).unwrap();
tx.delete("test", &id).unwrap();
let read_opt = tx.read("test", &id).unwrap();
assert_eq!(read_opt, None);
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let read_after = persy.read("test", &id).unwrap();
assert_eq!(read_after, None);
});
}
#[test]
fn test_update_delete_same_tx() {
create_and_drop("uds", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let bytes = String::from("something").into_bytes();
let id = tx.insert("test", &bytes).unwrap();
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let mut tx = persy.begin().unwrap();
let bytes = String::from("first").into_bytes();
tx.update("test", &id, &bytes).unwrap();
tx.delete("test", &id).unwrap();
let read_opt = tx.read("test", &id).unwrap();
assert_eq!(read_opt, None);
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let read_after = persy.read("test", &id).unwrap();
assert_eq!(read_after, None);
});
}
#[test]
fn test_insert_100_same_tx() {
create_and_drop("i100", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let bytes = String::from("something").into_bytes();
for _ in [0; 100].iter() {
tx.insert("test", &bytes).unwrap();
}
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let mut count = 0;
for _ in persy.scan("test").unwrap() {
count += 1;
}
assert_eq!(count, 100);
});
}
#[test]
fn test_update_100_same_tx() {
create_and_drop("i100", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let bytes = String::from("something").into_bytes();
let mut ids = Vec::new();
for _ in [0; 100].iter() {
ids.push(tx.insert("test", &bytes).unwrap());
}
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let mut tx = persy.begin().unwrap();
for id in ids {
tx.update("test", &id, &bytes).unwrap();
}
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let mut count = 0;
for _ in persy.scan("test").unwrap() {
count += 1;
}
assert_eq!(count, 100);
});
}
#[test]
fn test_create_insert_scan_same_tx() {
create_and_drop("cistx", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let bytes = String::from("something").into_bytes();
for _ in [0; 50].iter() {
tx.insert("test", &bytes).unwrap();
}
let mut count = 0;
for (_, content) in tx.scan("test").unwrap() {
assert_eq!(content, bytes);
count += 1;
}
assert_eq!(count, 50);
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
});
}
#[test]
fn test_create_insert_scan_same_tx_access() {
create_and_drop("cistx", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
tx.create_segment("test1").unwrap();
let bytes = String::from("something").into_bytes();
for _ in [0; 50].iter() {
tx.insert("test", &bytes).unwrap();
}
let mut count = 0;
let mut iter = tx.scan("test").unwrap();
iter.tx().insert("test1", "bytes".as_bytes()).unwrap();
let new_bytes = String::from("other").into_bytes();
while let Some((id, content, tx)) = iter.next_tx() {
assert_eq!(content, bytes);
count += 1;
tx.update("test", &id, &new_bytes).unwrap();
}
assert_eq!(count, 50);
let mut count = 0;
for (_, content) in tx.scan("test").unwrap() {
assert_eq!(content, new_bytes);
count += 1;
}
assert_eq!(count, 50);
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
});
}
#[test]
fn test_insert_100_and_scan_same_tx() {
create_and_drop("i100tx", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let bytes = String::from("something").into_bytes();
for _ in [0; 50].iter() {
tx.insert("test", &bytes).unwrap();
}
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let mut tx = persy.begin().unwrap();
for _ in [0; 50].iter() {
tx.insert("test", &bytes).unwrap();
}
let mut count = 0;
for (_, content) in tx.scan("test").unwrap() {
assert_eq!(content, bytes);
count += 1;
}
assert_eq!(count, 100);
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
});
}
#[test]
fn test_insert_100_update_and_scan_same_tx() {
create_and_drop("i100u_tx", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("test").unwrap();
let bytes = String::from("something").into_bytes();
let mut inserted = Vec::new();
for _ in [0; 50].iter() {
inserted.push(tx.insert("test", &bytes).unwrap());
}
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
let bytes_other = String::from("other").into_bytes();
let mut tx = persy.begin().unwrap();
for _ in [0; 50].iter() {
tx.insert("test", &bytes).unwrap();
}
for id in inserted.iter() {
tx.update("test", id, &bytes_other).unwrap();
}
let mut count = 0;
for (id, content) in tx.scan("test").unwrap() {
if inserted.contains(&id) {
assert_eq!(content, bytes_other);
} else {
assert_eq!(content, bytes);
}
count += 1;
}
assert_eq!(count, 100);
let finalizer = tx.prepare().unwrap();
finalizer.commit().unwrap();
});
}
#[test]
fn test_scan_tx_segment_not_exist() {
create_and_drop("sne_tx", |persy| {
let mut tx = persy.begin().unwrap();
let res = tx.scan("test");
if let Err(x) = res {
match x.error() {
SegmentError::SegmentNotFound => {}
_ => assert!(false),
}
} else {
assert!(false);
}
});
}
#[test]
fn test_concurrency_version_on_write() {
let mut config = Config::new();
config.change_tx_strategy(TxStrategy::VersionOnWrite);
create_and_drop_with_config("cvow", config, |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("seg").unwrap();
let bytes = String::from("aaa").into_bytes();
let id = tx.insert("seg", &bytes).unwrap();
let prep = tx.prepare().unwrap();
prep.commit().unwrap();
let bytes2 = String::from("bbb").into_bytes();
let mut tx = persy.begin().unwrap();
tx.update("seg", &id, &bytes2).unwrap();
let bytes3 = String::from("cccc").into_bytes();
let mut tx1 = persy.begin().unwrap();
tx1.update("seg", &id, &bytes3).unwrap();
let prep = tx1.prepare().unwrap();
prep.commit().unwrap();
let to_fail = tx.prepare();
assert!(to_fail.is_err());
let val = persy.read("seg", &id).unwrap().unwrap();
assert_eq!(val, bytes3);
});
}
#[test]
fn test_concurrency_last_win() {
let mut config = Config::new();
config.change_tx_strategy(TxStrategy::LastWin);
create_and_drop_with_config("cvol", config, |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("seg").unwrap();
let bytes = String::from("aaa").into_bytes();
let id = tx.insert("seg", &bytes).unwrap();
let prep = tx.prepare().unwrap();
prep.commit().unwrap();
let bytes2 = String::from("bbb").into_bytes();
let mut tx = persy.begin().unwrap();
tx.update("seg", &id, &bytes2).unwrap();
let bytes3 = String::from("cccc").into_bytes();
let mut tx1 = persy.begin().unwrap();
tx1.update("seg", &id, &bytes3).unwrap();
let prep = tx1.prepare().unwrap();
prep.commit().unwrap();
let prep = tx.prepare().unwrap();
prep.commit().unwrap();
let val = persy.read("seg", &id).unwrap().unwrap();
assert_eq!(val, bytes2);
});
}
#[test]
fn test_concurrency_version_on_read() {
let mut config = Config::new();
config.change_tx_strategy(TxStrategy::VersionOnRead);
create_and_drop_with_config("cvor", config, |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("seg").unwrap();
let bytes = String::from("aaa").into_bytes();
let id = tx.insert("seg", &bytes).unwrap();
let prep = tx.prepare().unwrap();
prep.commit().unwrap();
let bytes2 = String::from("bbb").into_bytes();
let mut tx = persy.begin().unwrap();
let _ = tx.read("seg", &id).unwrap();
let bytes3 = String::from("cccc").into_bytes();
let mut tx1 = persy.begin().unwrap();
tx1.update("seg", &id, &bytes3).unwrap();
let prep = tx1.prepare().unwrap();
prep.commit().unwrap();
tx.update("seg", &id, &bytes2).unwrap();
let to_fail = tx.prepare();
assert!(to_fail.is_err());
let val = persy.read("seg", &id).unwrap().unwrap();
assert_eq!(val, bytes3);
});
}
#[test]
fn test_scan_segment_not_exist() {
create_and_drop("sne", |persy| {
let res = persy.scan("test");
if let Err(x) = res {
match x.error() {
SegmentError::SegmentNotFound => {}
_ => assert!(false),
}
} else {
assert!(false);
}
});
}
#[test]
fn test_cleanup_after_delete() {
create_and_drop("cleanup_after_delete", |persy| {
let mut tx = persy.begin().unwrap();
tx.create_segment("one").unwrap();
tx.prepare().unwrap().commit().unwrap();
let mut tx = persy.begin().unwrap();
for _i in 0..5000 {
tx.insert("one", "two".as_bytes()).unwrap();
}
tx.prepare().unwrap().commit().unwrap();
let mut tx = persy.begin().unwrap();
for (id, _rec) in persy.scan("one").unwrap() {
tx.delete("one", &id).unwrap();
}
tx.prepare().unwrap().commit().unwrap();
assert!(persy.scan("one").unwrap().next().is_none());
});
}