@@ -623,6 +623,46 @@ mod tests {
623623 ) ;
624624 }
625625
626+ /// Tests that the buffer is never allowed to fill so much that it cannot
627+ /// fit a loss record. This reproduces a panic where there was insufficient
628+ /// space to record a loss record.
629+ #[ test]
630+ fn data_loss_on_full_queue ( ) {
631+ let mut s = Store :: < 64 > :: DEFAULT ;
632+ s. initialize ( OUR_FAKE_TID , 1 ) ;
633+ consume_initial_loss ( & mut s) ;
634+
635+ // Fill half the buffer.
636+ s. insert ( ANOTHER_FAKE_TID , 5 , & [ 0 ; 32 - OVERHEAD ] ) ;
637+ // Try to fill the other half of the buffer, *to the brim*. Allowing
638+ // this record in will mean that the buffer no longer has space for a
639+ // last loss record, so this record should *not* be accepted.
640+ s. insert ( ANOTHER_FAKE_TID , 6 , & [ 0 ; 32 - OVERHEAD ] ) ;
641+ // This one definitely gets lost.
642+ s. insert ( ANOTHER_FAKE_TID , 7 , & [ 0 ; 32 - OVERHEAD ] ) ;
643+
644+ let snapshot: Vec < Item < Vec < u8 > > > = copy_contents_raw ( & mut s) ;
645+ assert_eq ! ( snapshot. len( ) , 2 , "{snapshot:?}" ) ;
646+ assert_eq ! (
647+ snapshot[ 0 ] ,
648+ Item {
649+ ena: 2 ,
650+ tid: ANOTHER_FAKE_TID ,
651+ timestamp: 5 ,
652+ contents: Vec :: from( [ 0 ; 32 - OVERHEAD ] )
653+ }
654+ ) ;
655+ assert_eq ! (
656+ snapshot[ 1 ] . decode_as:: <LossRecord >( ) ,
657+ Item {
658+ ena: 3 ,
659+ tid: OUR_FAKE_TID ,
660+ timestamp: 6 ,
661+ contents: LossRecord { lost: Some ( 2 ) } ,
662+ }
663+ ) ;
664+ }
665+
626666 /// Arranges for the queue to contain: valid data; a loss record; more valid
627667 /// data. This helps exercise recovery behavior.
628668 #[ test]
0 commit comments