#![cfg(feature = "reassembler")]
use flowscope::{Reassembler, SegmentBufferReassembler, Timestamp};
fn ts(s: u32) -> Timestamp {
Timestamp::new(s, 0)
}
#[test]
fn no_overlap_no_inconsistency() {
let mut r = SegmentBufferReassembler::new();
r.segment(1000, b"hello", ts(0));
r.segment(1005, b" world", ts(0));
assert_eq!(r.rexmit_inconsistencies(), 0);
}
#[test]
fn ooo_segment_with_matching_overlap_is_not_an_inconsistency() {
let mut r = SegmentBufferReassembler::new();
r.segment(1000, b"hello", ts(0));
r.segment(1010, b"world", ts(1));
r.segment(1010, b"world", ts(2)); assert_eq!(r.rexmit_inconsistencies(), 0);
}
#[test]
fn ooo_segment_with_diverging_overlap_is_an_inconsistency() {
let mut r = SegmentBufferReassembler::new();
r.segment(1000, b"hello", ts(0));
r.segment(1010, b"world", ts(1));
r.segment(1010, b"WORLD", ts(2)); assert_eq!(r.rexmit_inconsistencies(), 1);
}
#[test]
fn partial_overlap_with_diverging_bytes_fires() {
let mut r = SegmentBufferReassembler::new();
r.segment(1000, b"hello", ts(0));
r.segment(1010, b"world", ts(1));
r.segment(1012, b"xyz12", ts(2));
assert_eq!(r.rexmit_inconsistencies(), 1);
}
#[test]
fn partial_overlap_with_matching_bytes_does_not_fire() {
let mut r = SegmentBufferReassembler::new();
r.segment(1000, b"hello", ts(0));
r.segment(1010, b"world", ts(1));
r.segment(1012, b"rldXY", ts(2));
assert_eq!(r.rexmit_inconsistencies(), 0);
}
#[test]
fn multiple_diverging_segments_count_independently() {
let mut r = SegmentBufferReassembler::new();
r.segment(1000, b"hello", ts(0));
r.segment(1010, b"world", ts(1));
r.segment(1010, b"WORLD", ts(2));
r.segment(1020, b"abcde", ts(3));
r.segment(1020, b"ABCDE", ts(4));
assert_eq!(r.rexmit_inconsistencies(), 2);
}
#[test]
fn trait_default_returns_zero_for_buffered_reassembler() {
let mut r = flowscope::BufferedReassembler::new();
r.segment(1000, b"hello", ts(0));
r.segment(1000, b"WORLD", ts(1));
assert!(r.retransmits() > 0);
assert_eq!(r.rexmit_inconsistencies(), 0);
}
#[test]
fn anomaly_kind_variant_has_stable_slug() {
use flowscope::{AnomalyKind, FlowSide};
let k = AnomalyKind::TcpRexmitInconsistency {
side: FlowSide::Initiator,
count: 3,
};
assert_eq!(k.short_kind(), "tcp_rexmit_inconsistency");
}
#[test]
fn anomaly_severity_is_error_not_info() {
use flowscope::event::Severity;
use flowscope::{AnomalyKind, FlowSide};
let k = AnomalyKind::TcpRexmitInconsistency {
side: FlowSide::Initiator,
count: 1,
};
assert_eq!(k.severity(), Severity::Error);
}