Skip to content

Commit 00c54f3

Browse files
committed
Add a property based test that tests basic functionality of the entity manager
1 parent 47cab9c commit 00c54f3

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

src/store/fs/util/entity_manager.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,21 @@ impl<P: Params> EntityManager<P> {
771771

772772
#[cfg(test)]
773773
mod tests {
774-
774+
//! Tests for the entity manager.
775+
//!
776+
//! We implement a simple database for u128 counters, identified by u64 ids,
777+
//! with both an in-memory and a file-based implementation.
778+
//!
779+
//! The database does internal consistency checks, to ensure that each
780+
//! entity is only ever accessed by a single tokio task at a time, and to
781+
//! ensure that wakeup and shutdown events are interleaved.
782+
//!
783+
//! We also check that the database behaves correctly by comparing with an
784+
//! in-memory implementation.
785+
//!
786+
//! Database operations are done in parallel, so the fact that we are using
787+
//! AtomicRefCell provides another test - if there was parallel write access
788+
//! to a single entity due to a bug, it would panic.
775789
use std::collections::HashMap;
776790

777791
use n0_future::{BufferedStreamExt, StreamExt};
@@ -793,6 +807,10 @@ mod tests {
793807
}
794808

795809
mod mem {
810+
//! The in-memory database uses a HashMap in the global state to store
811+
//! the values of the counters. Loading means reading from the global
812+
//! state into the entity state, and persisting means writing to the
813+
//! global state from the entity state.
796814
use std::{
797815
collections::{HashMap, HashSet},
798816
sync::{Arc, Mutex},
@@ -957,6 +975,7 @@ mod tests {
957975
}
958976

959977
mod fs {
978+
//! The fs db uses one file per counter, stored as a 16-byte big-endian u128.
960979
use std::{
961980
collections::HashSet,
962981
path::{Path, PathBuf},
@@ -1121,6 +1140,15 @@ mod tests {
11211140

11221141
async fn check_consistency(&self, values: HashMap<u64, u128>) {
11231142
let global = self.global.lock().unwrap();
1143+
for (id, value) in &values {
1144+
let path = get_path(&global.path, *id);
1145+
let disk_value = match std::fs::read(path) {
1146+
Ok(data) => u128::from_be_bytes(data.try_into().unwrap()),
1147+
Err(e) if e.kind() == std::io::ErrorKind::NotFound => 0,
1148+
Err(_) => panic!("Failed to read disk state for id {id}"),
1149+
};
1150+
assert_eq!(disk_value, *value, "Disk value mismatch for id {id}");
1151+
}
11241152
for id in values.keys() {
11251153
let log = global.log.get(&id).unwrap();
11261154
assert!(

0 commit comments

Comments
 (0)