mod helpers;
use helpers::{create_and_drop, CountDown};
use persy::PersyError;
use std::sync::Arc;
use std::thread;
#[test]
fn test_create_drop_segment() {
create_and_drop("cds", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
assert!(persy.exists_segment("test").unwrap());
let mut tx = persy.begin().unwrap();
persy.drop_segment(&mut tx, "test").unwrap();
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
assert!(!persy.exists_segment("test").unwrap());
});
}
#[test]
fn test_create_drop_double_segments_and_insert_data() {
create_and_drop("cdss", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
persy.create_segment(&mut tx, "test1").unwrap();
let bytes = String::from("some").into_bytes();
persy.insert_record(&mut tx, "test", &bytes).unwrap();
let bytes = String::from("some").into_bytes();
persy.insert_record(&mut tx, "test1", &bytes).unwrap();
{
let scanner = persy.scan_tx(&mut tx, "test").unwrap();
assert_eq!(1, scanner.into_iter().count());
}
let scanner = persy.scan_tx(&mut tx, "test1").unwrap();
assert_eq!(1, scanner.into_iter().count());
});
}
#[test]
fn test_create_drop_segment_same_tx() {
create_and_drop("cdss", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
assert!(persy.exists_segment_tx(&mut tx, "test").unwrap());
let err = persy.drop_segment(&mut tx, "test");
assert!(err.is_err());
});
}
#[test]
fn test_create_drop_recreate_segment_same_tx() {
create_and_drop("cdcs", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
assert!(persy.exists_segment_tx(&mut tx, "test").unwrap());
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
let mut tx = persy.begin().unwrap();
persy.drop_segment(&mut tx, "test").unwrap();
assert!(!persy.exists_segment_tx(&mut tx, "test").unwrap());
persy.create_segment(&mut tx, "test").unwrap();
assert!(persy.exists_segment_tx(&mut tx, "test").unwrap());
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
assert!(persy.exists_segment("test").unwrap());
});
}
#[test]
fn test_update_record_of_dropped_segment_other_tx() {
create_and_drop("urds", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
let bytes = String::from("some").into_bytes();
let rec = persy.insert_record(&mut tx, "test", &bytes).unwrap();
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
let mut tx = persy.begin().unwrap();
persy.update_record(&mut tx, "test", &rec, &bytes).unwrap();
let mut tx1 = persy.begin().unwrap();
persy.drop_segment(&mut tx1, "test").unwrap();
let finalizer = persy.prepare_commit(tx1).unwrap();
persy.commit(finalizer).unwrap();
let finalizer = persy.prepare_commit(tx);
assert!(finalizer.is_err());
});
}
#[test]
fn test_update_record_of_dropped_recreated_segment_other_tx() {
create_and_drop("urdcs", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
let bytes = String::from("some").into_bytes();
let rec = persy.insert_record(&mut tx, "test", &bytes).unwrap();
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
let mut tx = persy.begin().unwrap();
persy.update_record(&mut tx, "test", &rec, &bytes).unwrap();
let mut tx1 = persy.begin().unwrap();
persy.drop_segment(&mut tx1, "test").unwrap();
persy.create_segment(&mut tx1, "test").unwrap();
let finalizer = persy.prepare_commit(tx1).unwrap();
persy.commit(finalizer).unwrap();
let finalizer = persy.prepare_commit(tx);
assert!(finalizer.is_err());
});
}
#[test]
fn test_delete_record_of_dropped_segment_other_tx() {
create_and_drop("drds", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
let bytes = String::from("some").into_bytes();
let rec = persy.insert_record(&mut tx, "test", &bytes).unwrap();
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
let mut tx = persy.begin().unwrap();
persy.delete_record(&mut tx, "test", &rec).unwrap();
let mut tx1 = persy.begin().unwrap();
persy.drop_segment(&mut tx1, "test").unwrap();
let finalizer = persy.prepare_commit(tx1).unwrap();
persy.commit(finalizer).unwrap();
let finalizer = persy.prepare_commit(tx);
assert!(finalizer.is_err());
});
}
#[test]
fn test_delete_record_of_dropped_created_segment_other_tx() {
create_and_drop("drdcs", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
let bytes = String::from("some").into_bytes();
let rec = persy.insert_record(&mut tx, "test", &bytes).unwrap();
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
let mut tx = persy.begin().unwrap();
persy.delete_record(&mut tx, "test", &rec).unwrap();
let mut tx1 = persy.begin().unwrap();
persy.drop_segment(&mut tx1, "test").unwrap();
persy.create_segment(&mut tx1, "test").unwrap();
let finalizer = persy.prepare_commit(tx1).unwrap();
persy.commit(finalizer).unwrap();
let finalizer = persy.prepare_commit(tx);
assert!(finalizer.is_err());
});
}
#[test]
fn test_insert_record_of_dropped_recreated_segment_other_tx() {
create_and_drop("irdcs", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
let bytes = String::from("some").into_bytes();
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
let mut tx = persy.begin().unwrap();
persy.insert_record(&mut tx, "test", &bytes).unwrap();
let mut tx1 = persy.begin().unwrap();
persy.drop_segment(&mut tx1, "test").unwrap();
persy.create_segment(&mut tx1, "test").unwrap();
let finalizer = persy.prepare_commit(tx1).unwrap();
persy.commit(finalizer).unwrap();
let finalizer = persy.prepare_commit(tx);
assert!(finalizer.is_err());
});
}
#[test]
fn test_insert_record_of_dropped_segment_other_tx() {
create_and_drop("irds", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
let bytes = String::from("some").into_bytes();
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
let mut tx = persy.begin().unwrap();
persy.insert_record(&mut tx, "test", &bytes).unwrap();
let mut tx1 = persy.begin().unwrap();
persy.drop_segment(&mut tx1, "test").unwrap();
let finalizer = persy.prepare_commit(tx1).unwrap();
persy.commit(finalizer).unwrap();
let finalizer = persy.prepare_commit(tx);
assert!(finalizer.is_err());
});
}
#[test]
fn test_record_of_drop_segment_same_tx() {
create_and_drop("rds", |persy| {
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
let mut tx = persy.begin().unwrap();
let bytes = String::from("some").into_bytes();
let id = persy
.insert_record(&mut tx, "test", &bytes)
.expect("insert record works");
persy.drop_segment(&mut tx, "test").unwrap();
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
let mut tx = persy.begin().unwrap();
persy.create_segment(&mut tx, "test").unwrap();
assert!(
match persy.update_record(&mut tx, "test", &id, &String::from("none").into_bytes()) {
Err(PersyError::RecordNotFound(ref id2)) if *id2 == id => true,
_ => false,
}
);
assert_eq!(persy.read_record_tx(&mut tx, "test", &id).ok(), Some(None));
let finalizer = persy.prepare_commit(tx).unwrap();
persy.commit(finalizer).unwrap();
});
}
#[test]
pub fn test_councurrent_double_create() {
create_and_drop("concurrent_segment_double_create.", |persy| {
let both_create = Arc::new(CountDown::new(2));
let end = Arc::new(CountDown::new(2));
for _ in [0; 2].iter() {
let both_create_moved = both_create.clone();
let end_moved = end.clone();
let persy = persy.clone();
thread::spawn(move || {
let mut tx = persy.begin().expect("error on transaction begin");
persy.create_segment(&mut tx, "def").expect("error on segment creation");
both_create_moved.count_down().expect("lock not panic");
both_create_moved.wait().expect("thread wait the other");
let fin = persy.prepare_commit(tx).expect("error on commit prepare");
persy.commit(fin).expect("error on commit");
end_moved.count_down().expect("lock not panic");
});
}
end.wait().expect("threas finisced");
assert!(persy.exists_segment("def").unwrap());
});
}
#[test]
pub fn test_councurrent_double_drop() {
create_and_drop("concurrent_segment_double_drop.", |persy| {
let mut tx = persy.begin().expect("error on transaction begin");
persy.create_segment(&mut tx, "def").expect("error on segment creation");
let fin = persy.prepare_commit(tx).expect("error on commit prepare");
persy.commit(fin).expect("error on commit");
let both_create = Arc::new(CountDown::new(2));
let end = Arc::new(CountDown::new(2));
for _ in [0; 2].iter() {
let both_create_moved = both_create.clone();
let end_moved = end.clone();
let persy = persy.clone();
thread::spawn(move || {
let mut tx = persy.begin().expect("error on transaction begin");
persy.drop_segment(&mut tx, "def").expect("error on segment creation");
both_create_moved.count_down().expect("lock not panic");
both_create_moved.wait().expect("thread wait the other");
let fin = persy.prepare_commit(tx).expect("error on commit prepare");
persy.commit(fin).expect("error on commit");
end_moved.count_down().expect("lock not panic");
});
}
end.wait().expect("threas finisced");
assert!(!persy.exists_segment("def").unwrap());
});
}
#[test]
pub fn test_list_segments() {
create_and_drop("test_list_segments", |persy| {
let mut tx = persy.begin().expect("error on transaction begin");
persy.create_segment(&mut tx, "def").expect("error on segment creation");
persy.create_segment(&mut tx, "two").expect("error on segment creation");
let fin = persy.prepare_commit(tx).expect("error on commit prepare");
persy.commit(fin).expect("error on commit");
let segments = persy.list_segments().expect("list segments works as expected");
assert_eq!(segments.len(), 2);
let names = segments.into_iter().map(|(name, _id)| name).collect::<Vec<String>>();
assert!(names.contains(&"def".to_string()));
assert!(names.contains(&"two".to_string()));
});
}
#[test]
pub fn test_list_segments_tx() {
create_and_drop("test_list_segments", |persy| {
let mut tx = persy.begin().expect("error on transaction begin");
persy.create_segment(&mut tx, "def").expect("error on segment creation");
persy.create_segment(&mut tx, "two").expect("error on segment creation");
let fin = persy.prepare_commit(tx).expect("error on commit prepare");
persy.commit(fin).expect("error on commit");
let mut tx = persy.begin().expect("error on transaction begin");
persy.drop_segment(&mut tx, "two").expect("error on segment drop");
persy
.create_segment(&mut tx, "three")
.expect("error on segment creation");
let segments = persy
.list_segments_tx(&mut tx)
.expect("list segments works as expected");
assert_eq!(segments.len(), 2);
let names = segments.into_iter().map(|x| x.0).collect::<Vec<String>>();
assert!(names.contains(&"def".to_string()));
assert!(names.contains(&"three".to_string()));
});
}