Skip to content

Commit 3a45b84

Browse files
committed
Add test cases to data_tracker
When looking for a bug (that showed not to be a bug), these test cases were added. Let's keep them, as they increase test coverage of the logic that merges adjacent gap-ack blocks.
1 parent a8e7340 commit 3a45b84

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

src/rx/data_tracker.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1238,4 +1238,68 @@ mod tests {
12381238
observe(&mut d, now, &[11]);
12391239
assert!(d.get_handover_readiness().is_ready());
12401240
}
1241+
1242+
#[test]
1243+
fn observe_out_of_order_and_fill_gap_moves_cumulative_tsn_ack() {
1244+
let now = Instant::now();
1245+
let mut d = DataTracker::new(INITIAL_TSN, &Options::default());
1246+
1247+
// Receive 12, 14, 15. Then 11 (which advances cum_ack), then 13 (which fills the gap).
1248+
observe(&mut d, now, &[12, 14, 15, 11, 13]);
1249+
1250+
let sack = d.create_selective_ack(A_RWND);
1251+
assert_eq!(sack.cumulative_tsn_ack, Tsn(15));
1252+
assert!(sack.gap_ack_blocks.is_empty());
1253+
assert!(sack.duplicate_tsns.is_empty());
1254+
}
1255+
1256+
#[test]
1257+
fn observe_out_of_order_and_fill_gap_moves_cumulative_tsn_ack_multiple_blocks() {
1258+
let now = Instant::now();
1259+
let mut d = DataTracker::new(INITIAL_TSN, &Options::default());
1260+
1261+
// Create two separate blocks: 12-13 and 15-16
1262+
observe(&mut d, now, &[12, 13, 15, 16]);
1263+
// Now fill the gap between them with 14. This should merge the blocks.
1264+
// The current implementation of `add_additional_tsn` is buggy and will
1265+
// result in `[12..14, 14..17]`.
1266+
observe(&mut d, now, &[14]);
1267+
// Now receive 11, which should advance the cumulative ack over all blocks.
1268+
observe(&mut d, now, &[11]);
1269+
1270+
let sack = d.create_selective_ack(A_RWND);
1271+
assert_eq!(sack.cumulative_tsn_ack, Tsn(16));
1272+
assert!(sack.gap_ack_blocks.is_empty());
1273+
assert!(sack.duplicate_tsns.is_empty());
1274+
}
1275+
1276+
#[test]
1277+
fn observe_fill_gap_of_three_blocks_advances_cumulative_tsn() {
1278+
let now = Instant::now();
1279+
let mut d = DataTracker::new(INITIAL_TSN, &Options::default());
1280+
1281+
// Create two separate blocks: 13 and 15.
1282+
// State: additional_tsn_blocks = [13..14, 15..16]
1283+
observe(&mut d, now, &[13, 15]);
1284+
1285+
// Fill the gap between them with 14.
1286+
// This hits a bug in `add_additional_tsn` where expanding a block to the left
1287+
// doesn't check if it can merge with the block before it, resulting in adjacent blocks.
1288+
// State: additional_tsn_blocks = [13..14, 14..16]
1289+
observe(&mut d, now, &[14]);
1290+
1291+
// Add 12, which expands the first block to the left.
1292+
// State: additional_tsn_blocks = [12..14, 14..16]
1293+
observe(&mut d, now, &[12]);
1294+
1295+
// Now receive 11, which should advance the cumulative ack over all blocks.
1296+
// But `observe` only processes one block, leaving last_cumulative_acked_tsn
1297+
// at 13 instead of 15.
1298+
observe(&mut d, now, &[11]);
1299+
1300+
let sack = d.create_selective_ack(A_RWND);
1301+
assert_eq!(sack.cumulative_tsn_ack, Tsn(15));
1302+
assert!(sack.gap_ack_blocks.is_empty());
1303+
assert!(sack.duplicate_tsns.is_empty());
1304+
}
12411305
}

0 commit comments

Comments
 (0)