@@ -115,3 +115,62 @@ fn available_buffer_size(read_cursor: usize, write_cursor: usize) -> usize {
115115 BUF_SIZE - write_cursor - 1 + read_cursor
116116 }
117117}
118+
119+ #[ cfg( test) ]
120+ mod tests {
121+ use super :: available_buffer_size;
122+ use crate :: consts:: BUF_SIZE ;
123+
124+ #[ test]
125+ fn test_rtt_available_buffer_size ( ) {
126+ // Helper to simulate RTT buffer state
127+ let avail = |read : usize , write : usize | available_buffer_size ( read, write) ;
128+
129+ // --- Case 1: Buffer is EMPTY (write == read) ---
130+ // Should have maximum available space: BUF_SIZE - 1
131+ assert_eq ! ( avail( 0 , 0 ) , BUF_SIZE - 1 ) ;
132+ assert_eq ! ( avail( 10 , 10 ) , BUF_SIZE - 1 ) ;
133+ assert_eq ! ( avail( BUF_SIZE - 1 , BUF_SIZE - 1 ) , BUF_SIZE - 1 ) ;
134+
135+ // --- Case 2: Buffer is FULL ---
136+ // Full condition: (write + 1) % BUF_SIZE == read
137+ // i.e., write == (read - 1 + BUF_SIZE) % BUF_SIZE
138+ assert_eq ! ( avail( 0 , BUF_SIZE - 1 ) , 0 ) ; // write=BUF_SIZE-1, read=0 → full
139+ assert_eq ! ( avail( 5 , 4 ) , 0 ) ; // write=4, read=5 → full
140+ assert_eq ! ( avail( 1 , 0 ) , 0 ) ; // write=0, read=1 → full
141+
142+ // --- Case 3: Read ahead of Write (no wrap-around) ---
143+ // e.g., read=10, write=5 → free space = [5..9] → size = 10 - 5 - 1 = 4
144+ assert_eq ! ( avail( 10 , 5 ) , 10 - 5 - 1 ) ;
145+ assert_eq ! ( avail( BUF_SIZE - 1 , 0 ) , ( BUF_SIZE - 1 ) - 0 - 1 ) ; // = BUF_SIZE - 2
146+
147+ // --- Case 4: Write has wrapped around, Read behind (wrap-around case) ---
148+ // e.g., read=5, write=10 → free space = [10..BUF_SIZE-1] + [0..4]
149+ // size = (BUF_SIZE - 10 - 1) + (5) = BUF_SIZE - 10 - 1 + 5
150+ assert_eq ! ( avail( 5 , 10 ) , BUF_SIZE - 10 - 1 + 5 ) ;
151+ assert_eq ! ( avail( 0 , 1 ) , BUF_SIZE - 1 - 1 + 0 ) ; // = BUF_SIZE - 2
152+ assert_eq ! ( avail( 1 , BUF_SIZE - 1 ) , BUF_SIZE - ( BUF_SIZE - 1 ) - 1 + 1 ) ; // = 1
153+
154+ // --- Edge: Single byte free ---
155+ // After filling BUF_SIZE - 2 bytes from empty, 1 byte remains
156+ assert_eq ! ( avail( 1 , BUF_SIZE - 1 ) , 1 ) ; // one byte free
157+ assert_eq ! ( avail( 2 , BUF_SIZE - 1 ) , 2 ) ; // one byte free: only position BUF_SIZE-1 is free? No.
158+ // Actually: write=BUF_SIZE-1, read=2 → free = [BUF_SIZE-1] + [0,1] → but [0,1] is 2 bytes?
159+ // Let's recompute: total free = (BUF_SIZE - (BUF_SIZE-1) - 1) + 2 = (0) + 2 = 2 → wait.
160+
161+ // Better: use invariant
162+ // Total data in buffer = (write - read + BUF_SIZE) % BUF_SIZE
163+ // Free = BUF_SIZE - 1 - data
164+ let data_in_buffer = |read : usize , write : usize | ( write + BUF_SIZE - read) % BUF_SIZE ;
165+ let free_should_be = |read : usize , write : usize | BUF_SIZE - 1 - data_in_buffer ( read, write) ;
166+
167+ // Validate our function against this invariant
168+ for read in 0 ..BUF_SIZE . min ( 64 ) {
169+ for write in 0 ..BUF_SIZE . min ( 64 ) {
170+ let expected = free_should_be ( read, write) ;
171+ let actual = avail ( read, write) ;
172+ assert_eq ! ( actual, expected, "Mismatch at read={read}, write={write}" ) ;
173+ }
174+ }
175+ }
176+ }
0 commit comments