@@ -771,7 +771,21 @@ impl<P: Params> EntityManager<P> {
771771
772772#[ cfg( test) ]
773773mod 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