tests: rework the actually useful tests to live in the integration crate
Rust CI / cargo fmt (push) Successful in 17s
Rust CI / cargo check (x86_64-unknown-linux-gnu) (push) Successful in 34s
Rust CI / cargo clippy (push) Successful in 35s
Rust CI / cargo check (x86_64-unknown-linux-musl) (push) Failing after 8s
Rust CI / cargo test (x86_64-unknown-linux-musl) (push) Failing after 10s
Rust CI / cargo test (x86_64-unknown-linux-gnu) (push) Successful in 1m14s
Rust CI / cargo doc (push) Successful in 23s
Fuzz Smoke / cargo fuzz smoke (push) Failing after 29s
Supply chain / cargo-deny advisories (push) Successful in 9s
Supply chain / cargo-deny bans licenses sources (push) Successful in 5s
Supply chain / actionlint (push) Successful in 3s
Netem Interop / netem interop (push) Successful in 1m11s
Rust CI / cargo fmt (push) Successful in 17s
Rust CI / cargo check (x86_64-unknown-linux-gnu) (push) Successful in 34s
Rust CI / cargo clippy (push) Successful in 35s
Rust CI / cargo check (x86_64-unknown-linux-musl) (push) Failing after 8s
Rust CI / cargo test (x86_64-unknown-linux-musl) (push) Failing after 10s
Rust CI / cargo test (x86_64-unknown-linux-gnu) (push) Successful in 1m14s
Rust CI / cargo doc (push) Successful in 23s
Fuzz Smoke / cargo fuzz smoke (push) Failing after 29s
Supply chain / cargo-deny advisories (push) Successful in 9s
Supply chain / cargo-deny bans licenses sources (push) Successful in 5s
Supply chain / actionlint (push) Successful in 3s
Netem Interop / netem interop (push) Successful in 1m11s
This commit is contained in:
101 files changed
+3636
-15159
No files matched your search
@@ -185,65 +185,13 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ipdv_tracker_late_wrapped_previous_completes_pair() {
|
||||
let mut tracker = IpdvTracker::new(None);
|
||||
assert!(tracker.insert(ipdv_sample(0, 14)).is_empty());
|
||||
|
||||
let pairs = tracker.insert(ipdv_sample(u32::MAX, 10));
|
||||
|
||||
assert_eq!(
|
||||
pairs,
|
||||
vec![CompletedIpdvPair {
|
||||
previous_seq: u32::MAX,
|
||||
current_seq: 0,
|
||||
rtt_ipdv_ns: 4,
|
||||
send_ipdv_ns: None,
|
||||
receive_ipdv_ns: None,
|
||||
}]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ipdv_tracker_bounded_mode_limits_sequence_state() {
|
||||
let limit = 4;
|
||||
let mut tracker = IpdvTracker::new(Some(limit));
|
||||
|
||||
// Far more inserts than the limit, so eviction runs repeatedly. Every
|
||||
// per-sequence collection must stay bounded by the limit rather than
|
||||
// growing with the number of samples seen, and eviction must not stop
|
||||
// adjacent sequences from still completing a pair.
|
||||
for seq in 0..512_u32 {
|
||||
let pairs = tracker.insert(ipdv_sample(seq, i128::from(seq)));
|
||||
|
||||
assert_eq!(pairs.len(), usize::from(seq > 0), "seq {seq}");
|
||||
assert!(tracker.samples.len() <= limit, "seq {seq}");
|
||||
assert_eq!(
|
||||
tracker.sample_order.len(),
|
||||
tracker.samples.len(),
|
||||
"seq {seq}"
|
||||
);
|
||||
assert!(tracker.completed_pairs.len() <= limit, "seq {seq}");
|
||||
}
|
||||
}
|
||||
|
||||
mod properties {
|
||||
use super::*;
|
||||
use proptest::prelude::*;
|
||||
|
||||
proptest! {
|
||||
/// The hand-written `ipdv_tracker_bounded_mode_limits_sequence_state`
|
||||
/// test above only exercises a strictly increasing `0..512`
|
||||
/// sequence. Real traffic can duplicate, skip, or otherwise not
|
||||
/// strictly increase sequence numbers (see the client's
|
||||
/// `LateReply`/`DuplicateReply` handling), so this generates
|
||||
/// arbitrary, possibly-repeated, possibly-non-monotonic sequence
|
||||
/// streams and checks the same bounds still hold after every
|
||||
/// insert: `samples` and `sample_order` never exceed the
|
||||
/// configured limit and stay in lockstep, and `completed_pairs`
|
||||
/// never exceeds `samples.len()` (a successful entry can only
|
||||
/// persist once both its endpoint samples are present, see
|
||||
/// `try_pair`, so it is always a subset of the live sample keys).
|
||||
// Hidden retention state must stay bounded even with duplicates,
|
||||
// gaps and reordered replies; snapshots cannot expose a leak here.
|
||||
#[test]
|
||||
fn bounded_tracker_state_never_exceeds_the_limit(
|
||||
limit in 1usize..8,
|
||||
@@ -251,34 +199,26 @@ mod tests {
|
||||
) {
|
||||
let mut tracker = IpdvTracker::new(Some(limit));
|
||||
for seq in seqs {
|
||||
tracker.insert(ipdv_sample(seq, i128::from(seq)));
|
||||
let completed_before = tracker.completed_pairs.clone();
|
||||
let pairs = tracker.insert(ipdv_sample(seq, i128::from(seq)));
|
||||
let emitted: HashSet<_> = pairs.iter().map(|pair| pair.current_seq).collect();
|
||||
prop_assert_eq!(emitted.len(), pairs.len());
|
||||
prop_assert!(emitted.is_disjoint(&completed_before), "a retained pair must not be emitted twice");
|
||||
prop_assert!(tracker.samples.len() <= limit);
|
||||
prop_assert!(tracker.sample_order.len() <= limit);
|
||||
prop_assert!(tracker.completed_pairs.len() <= limit);
|
||||
// Eviction must remove stale pair markers as well as samples;
|
||||
// otherwise retained state can prevent future adjacent pairs.
|
||||
prop_assert_eq!(tracker.sample_order.len(), tracker.samples.len());
|
||||
prop_assert!(tracker.completed_pairs.len() <= tracker.samples.len());
|
||||
prop_assert_eq!(tracker.sample_order.iter().collect::<HashSet<_>>().len(), tracker.samples.len());
|
||||
prop_assert!(tracker.sample_order.iter().all(|seq| tracker.samples.contains_key(seq)));
|
||||
prop_assert!(tracker.completed_pairs.iter().all(|seq| {
|
||||
tracker.samples.contains_key(seq)
|
||||
&& tracker.samples.contains_key(&seq.wrapping_sub(1))
|
||||
}), "completed pairs must retain both sequence endpoints");
|
||||
}
|
||||
}
|
||||
|
||||
/// A pair for a given adjacent `(seq - 1, seq)` boundary is only
|
||||
/// ever emitted once, however many times `insert` is called
|
||||
/// (including for already-seen or unrelated sequences in
|
||||
/// between). This is the unbounded case, so eviction cannot be
|
||||
/// the reason a pair fails to repeat.
|
||||
#[test]
|
||||
fn each_adjacent_pair_is_emitted_at_most_once(
|
||||
seqs in prop::collection::vec(0u32..12, 0..200),
|
||||
) {
|
||||
let mut tracker = IpdvTracker::new(None);
|
||||
let mut seen_pairs = std::collections::HashSet::new();
|
||||
for seq in seqs {
|
||||
for pair in tracker.insert(ipdv_sample(seq, i128::from(seq))) {
|
||||
let key = (pair.previous_seq, pair.current_seq);
|
||||
prop_assert!(
|
||||
seen_pairs.insert(key),
|
||||
"pair {key:?} emitted more than once"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user