@@ -870,9 +870,9 @@ async fn test_v1_wait() -> std::io::Result<()> {
870870 Ok ( ( ) )
871871}
872872
873- // FIXME test is a bit slow and flakey, how to improve?
874- // unfortunately tokio::time::pause() can't be used because this uses SystemTime
875- // as the underlying clock type, due to timestamps originating from disk
873+ // Simulate elapsed time deterministically by shifting stored timestamps
874+ // backward instead of sleeping. tokio::time::pause() can't be used because
875+ // prune compares against SystemTime ( timestamps originate from disk).
876876#[ tokio:: test]
877877async fn test_prune ( ) -> std:: io:: Result < ( ) > {
878878 let dir = tempfile:: tempdir ( ) ?;
@@ -881,12 +881,16 @@ async fn test_prune() -> std::io::Result<()> {
881881 . await
882882 . expect ( "initializing mailbox database should succeed" ) ;
883883
884+ let read_ttl = Duration :: from_secs ( 60 ) ;
885+ let unread_ttl_at_capacity = Duration :: from_secs ( 600 ) ;
886+ let unread_ttl_below_capacity = Duration :: from_secs ( 3600 ) ;
887+
884888 {
885889 let mut guard = db. mailboxes . lock ( ) . await ;
886890 guard. capacity = 2 ;
887- guard. read_ttl = Duration :: from_millis ( 10 ) ;
888- guard. unread_ttl_at_capacity = Duration :: from_millis ( 100 ) ;
889- guard. unread_ttl_below_capacity = Duration :: from_millis ( 200 ) ;
891+ guard. read_ttl = read_ttl ;
892+ guard. unread_ttl_at_capacity = unread_ttl_at_capacity ;
893+ guard. unread_ttl_below_capacity = unread_ttl_below_capacity ;
890894 }
891895
892896 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 0 ) ;
@@ -896,6 +900,7 @@ async fn test_prune() -> std::io::Result<()> {
896900 let id = ShortId ( [ 0u8 ; 8 ] ) ;
897901 let contents = b"fooo" ;
898902
903+ // Pending v2 waiter that times out should be cleaned up by prune
899904 let read_task1 = tokio:: spawn ( {
900905 let db = db. clone ( ) ;
901906 async move { db. wait_for_v2_payload ( & id) . await }
@@ -906,12 +911,13 @@ async fn test_prune() -> std::io::Result<()> {
906911
907912 match read_task1. await . expect ( "joining should succeed" ) {
908913 Err ( super :: Error :: Timeout ( _) ) => { }
909- res => panic ! ( "expected timeout, got {:?}" , res ) ,
914+ res => panic ! ( "expected timeout, got {res :?}" ) ,
910915 }
911916
912917 db. prune ( ) . await . expect ( "pruning should not fail" ) ;
913918 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 0 ) ;
914919
920+ // Post a v2 payload — should survive immediate prune (TTL not elapsed)
915921 db. post_v2_payload ( & id, contents. to_vec ( ) )
916922 . await
917923 . expect ( "posting payload should succeed" )
@@ -921,42 +927,46 @@ async fn test_prune() -> std::io::Result<()> {
921927 db. prune ( ) . await . expect ( "pruning should not fail" ) ;
922928 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 1 ) ;
923929
924- tokio:: time:: sleep ( Duration :: from_millis ( 200 ) ) . await ;
930+ // Shift insert timestamps past unread_ttl_below_capacity
931+ {
932+ let mut guard = db. mailboxes . lock ( ) . await ;
933+ for ( ts, _) in guard. insert_order . iter_mut ( ) {
934+ * ts -= unread_ttl_below_capacity + Duration :: from_secs ( 1 ) ;
935+ }
936+ }
925937
926938 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 1 ) ;
927939 db. prune ( ) . await . expect ( "pruning should not fail" ) ;
928940 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 0 ) ;
929941
942+ // Post again, read it, then verify read TTL pruning
930943 db. post_v2_payload ( & id, contents. to_vec ( ) )
931944 . await
932945 . expect ( "posting payload should succeed" )
933946 . expect ( "contents should be accepted" ) ;
934947
935948 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 1 ) ;
936- // FIXME why does this fail?
937- // db.prune().await.expect("pruning should not fail");
938- // assert_eq!(db.mailboxes.lock().await.len(), 1);
939- // mailbox seems to get pruned prematurely
940- // likely cause is it's in both read and insert queue, and two pruning runs
941- // are needed to fully clear it?
942-
943- // mark the mailbox as read
949+
950+ // Mark the mailbox as read
944951 _ = db. wait_for_v2_payload ( & id) . await . expect ( "waiting for payload should succeed" ) ;
945952
946953 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 1 ) ;
947- // FIXME db.prune().await.expect("pruning should not fail");
954+ db. prune ( ) . await . expect ( "pruning should not fail" ) ;
948955 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 1 ) ;
949956
950- // allow read TTL to elapse
951- tokio:: time:: sleep ( Duration :: from_millis ( 10 ) ) . await ;
957+ // Shift read timestamps past read_ttl
958+ {
959+ let mut guard = db. mailboxes . lock ( ) . await ;
960+ for ( ts, _) in guard. read_order . iter_mut ( ) {
961+ * ts -= read_ttl + Duration :: from_secs ( 1 ) ;
962+ }
963+ }
952964
953965 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 1 ) ;
954966 db. prune ( ) . await . expect ( "pruning should not fail" ) ;
955967 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 0 ) ;
956968
957- tokio:: time:: sleep ( Duration :: from_millis ( 200 ) ) . await ;
958-
959- assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 0 ) ;
969+ // Empty db should remain empty after prune
960970 db. prune ( ) . await . expect ( "pruning should not fail" ) ;
961971 assert_eq ! ( db. mailboxes. lock( ) . await . len( ) , 0 ) ;
962972
0 commit comments