blob: 1a5b5472ec64631f0089bb50eba90790bcaa7101 [file] [log] [blame]
use {
crate::{
lsm_tree::LSMTree,
object_handle::ObjectHandle,
object_store::{
filesystem::{Filesystem, SyncOptions},
log::Transaction,
merge,
record::{ExtentKey, ObjectItem, ObjectKey, ObjectValue},
HandleOptions,
},
testing::fake_device::FakeDevice,
},
anyhow::Error,
std::sync::Arc,
};
#[test]
fn test_object_store() -> Result<(), Error> {
let device = Arc::new(FakeDevice::new(512));
let object_id;
{
let mut filesystem = Filesystem::new_empty(device.clone())?;
let root_store = filesystem.root_store();
let mut transaction = Transaction::new();
let handle = root_store
.create_object(&mut transaction, HandleOptions::default())
.expect("create_object failed");
root_store.log().commit(transaction);
object_id = handle.object_id();
handle.write(5, b"hello").expect("write failed");
{
let mut buf = [0; 5];
handle.read(5, &mut buf).expect("read failed");
}
handle.write(6, b"hello").expect("write failed");
{
let mut buf = [0; 6];
handle.read(5, &mut buf).expect("read failed");
}
filesystem.sync(SyncOptions::default()).expect("sync failed");
}
let object_id2;
{
let mut filesystem = Filesystem::open(device.clone()).expect("open failed");
let root_store = filesystem.root_store();
let handle = root_store
.open_object(object_id, HandleOptions::default())
.expect("open_object failed");
let mut buf = [0; 5];
handle.read(6, &mut buf).expect("read failed");
assert_eq!(&buf, b"hello");
let mut transaction = Transaction::new();
let handle = root_store
.create_object(&mut transaction, HandleOptions::default())
.expect("create_object failed");
root_store.log().commit(transaction);
object_id2 = handle.object_id();
handle.write(5000, b"foo").expect("write failed");
filesystem
.sync(SyncOptions { new_super_block: true, ..Default::default() })
.expect("sync failed");
}
{
let mut filesystem = Filesystem::open(device.clone()).expect("open failed");
let root_store = filesystem.root_store();
let handle = root_store
.open_object(object_id2, HandleOptions::default())
.expect("open_object failed");
let mut buf = [0; 3];
handle.read(5000, &mut buf).expect("read failed");
assert_eq!(&buf, b"foo");
root_store.flush(true).expect("flush failed");
filesystem
.sync(SyncOptions { new_super_block: true, ..Default::default() })
.expect("sync failed");
}
let mut object_ids = Vec::new();
{
let filesystem = Filesystem::open(device.clone()).expect("open failed");
let root_store = filesystem.root_store();
for _i in 0..500 {
let mut transaction = Transaction::new();
let handle = root_store
.create_object(&mut transaction, HandleOptions::default())
.expect("create_object failed");
root_store.log().commit(transaction);
object_ids.push(handle.object_id());
handle.write(10000, b"bar").expect("write failed");
}
}
{
let filesystem = Filesystem::open(device.clone()).expect("open failed");
let root_store = filesystem.root_store();
let handle = root_store
.open_object(object_ids[0], HandleOptions::default())
.expect("open_object failed");
let mut buf = [0; 3];
handle.read(10000, &mut buf).expect("read failed");
assert_eq!(&buf, b"bar");
}
Ok(())
}
#[test]
fn test_extents_merging() -> Result<(), Error> {
let tree = LSMTree::new(merge::merge);
let item = ObjectItem {
key: ObjectKey::extent(0, ExtentKey::new(0, 0..10)),
value: ObjectValue::extent(0),
};
let lower_bound = item.key.lower_bound();
tree.replace_range(item, &lower_bound);
let item = ObjectItem {
key: ObjectKey::extent(0, ExtentKey::new(0, 3..7)),
value: ObjectValue::extent(0),
};
let lower_bound = item.key.lower_bound();
tree.replace_range(item, &lower_bound);
tree.dump_mutable_layer();
{
let mut iter = tree.iter();
iter.advance()?;
assert_eq!(iter.get().unwrap().key, &ObjectKey::extent(0, ExtentKey::new(0, 0..3)));
iter.advance()?;
assert_eq!(iter.get().unwrap().key, &ObjectKey::extent(0, ExtentKey::new(0, 3..7)));
iter.advance()?;
assert_eq!(iter.get().unwrap().key, &ObjectKey::extent(0, ExtentKey::new(0, 7..10)));
iter.advance()?;
assert!(iter.get().is_none());
}
{
let mut iter = tree.iter();
iter.advance()?;
assert_eq!(iter.get().unwrap().key, &ObjectKey::extent(0, ExtentKey::new(0, 0..3)));
iter.advance()?;
assert_eq!(iter.get().unwrap().key, &ObjectKey::extent(0, ExtentKey::new(0, 3..7)));
iter.advance()?;
assert_eq!(iter.get().unwrap().key, &ObjectKey::extent(0, ExtentKey::new(0, 7..10)));
iter.advance()?;
assert!(iter.get().is_none());
}
let item = ObjectItem {
key: ObjectKey::extent(0, ExtentKey::new(0, 2..9)),
value: ObjectValue::extent(0),
};
let lower_bound = item.key.lower_bound();
tree.replace_range(item, &lower_bound);
{
let mut iter = tree.iter();
iter.advance()?;
assert_eq!(iter.get().unwrap().key, &ObjectKey::extent(0, ExtentKey::new(0, 0..2)));
iter.advance()?;
assert_eq!(iter.get().unwrap().key, &ObjectKey::extent(0, ExtentKey::new(0, 2..9)));
iter.advance()?;
assert_eq!(iter.get().unwrap().key, &ObjectKey::extent(0, ExtentKey::new(0, 9..10)));
iter.advance()?;
assert!(iter.get().is_none());
}
Ok(())
}
#[test]
fn test_directory() -> Result<(), Error> {
let device = Arc::new(FakeDevice::new(512));
let directory_id;
{
let mut filesystem = Filesystem::new_empty(device.clone())?;
let root_store = filesystem.root_store();
let mut directory = root_store.create_directory().expect("create_directory failed");
directory.create_child_file("foo").expect("create_child_file failed");
directory_id = directory.object_id();
let directory = root_store.open_directory(directory_id).expect("open directory failed");
directory.lookup("foo").expect("open foo failed");
directory.lookup("bar").map(|_| ()).expect_err("open bar succeeded");
filesystem.sync(SyncOptions::default()).expect("sync failed");
}
{
let filesystem = Filesystem::open(device.clone())?;
let root_store = filesystem.root_store();
let directory = root_store.open_directory(directory_id).expect("open directory failed");
directory.lookup("foo").expect("open foo failed");
directory.lookup("bar").map(|_| ()).expect_err("open bar succeeded");
}
Ok(())
}