use std::path::Path;
use crate::common::counter::hardware_counter::HardwareCounterCell;
use rstest::rstest;
use super::PayloadStorage;
use super::mmap_payload_storage::MmapPayloadStorage;
use crate::segment::payload_json;
fn test_trait_impl<S: PayloadStorage>(open: impl Fn(&Path) -> S) {
let dir = tempfile::tempdir().unwrap();
let mut storage = open(dir.path());
assert_eq!(storage.get_storage_size_bytes().unwrap(), 0);
let payload = payload_json! {
"a": "some text",
};
let hw_counter = HardwareCounterCell::new();
storage.set(0, &payload, &hw_counter).unwrap();
assert_eq!(storage.get(0, &hw_counter).unwrap(), payload);
let payload_to_merge = payload_json! {
"zzz": "some other text",
};
storage.set(0, &payload_to_merge, &hw_counter).unwrap();
let stored = storage.get(0, &hw_counter).unwrap();
assert_eq!(
stored,
payload_json! {
"a": "some text",
"zzz": "some other text",
},
);
let nested_payload = payload_json! {
"layer2": true,
};
storage
.set_by_key(
0,
&nested_payload,
&"layer1".try_into().unwrap(),
&hw_counter,
)
.unwrap();
let stored = storage.get(0, &hw_counter).unwrap();
assert_eq!(
stored,
payload_json! {
"a": "some text",
"zzz": "some other text",
"layer1": {
"layer2": true,
}
},
);
storage
.delete(0, &"layer1".try_into().unwrap(), &hw_counter)
.unwrap();
let stored = storage.get(0, &hw_counter).unwrap();
assert_eq!(
stored,
payload_json! {
"a": "some text",
"zzz": "some other text",
},
);
let new_payload = payload_json! {
"new": "new text",
"other_new": "other new text",
};
storage.overwrite(0, &new_payload, &hw_counter).unwrap();
let stored = storage.get(0, &hw_counter).unwrap();
assert_eq!(stored, new_payload);
storage.clear(0, &hw_counter).unwrap();
assert_eq!(storage.get(0, &hw_counter).unwrap(), payload_json! {});
for i in 1..10 {
storage.set(i, &payload, &hw_counter).unwrap();
}
let assert_payloads = |storage: &S| {
storage
.iter(
|key, value| {
if key == 0 {
assert_eq!(value, &payload_json! {});
return Ok(true);
}
assert_eq!(value, &payload);
Ok(true)
},
&hw_counter,
)
.unwrap();
};
assert_payloads(&storage);
eprintln!("storage is correct before drop");
storage.flusher()().unwrap();
drop(storage);
let storage = open(dir.path());
assert_payloads(&storage);
eprintln!("storage is correct after drop");
assert!(storage.get_storage_size_bytes().unwrap() > 0);
}
#[rstest]
fn test_mmap_storage(#[values(false, true)] populate: bool) {
test_trait_impl(|path| {
MmapPayloadStorage::open_or_create(path.to_path_buf(), populate).unwrap()
});
}