Merge branch 'master'

Carries the rekey counter-arm boundary test and the removal of the
closure-based trigger test. Applied cleanly with no adaptation: the
trigger predicate is byte-identical on both lines, and the claim the new
test rests on was re-measured here rather than assumed to carry — widening
the bound to `p.counter >= 1` reds exactly one test on this line too.
This commit is contained in:
Johnathan Corgan
2026-07-25 00:40:14 +00:00
2 changed files with 37 additions and 35 deletions
+8 -30
View File
@@ -1314,36 +1314,14 @@ mod overlapping_epoch_tests {
);
}
// Rekey-trigger threshold: elapsed time (with symmetric jitter applied)
// OR the send counter crossing its configured bound.
#[test]
fn rekey_trigger_threshold_arithmetic() {
let after_secs = 100u64;
let after_messages = 1_000u64;
// Jitter is always within [-REKEY_JITTER_SECS, +REKEY_JITTER_SECS].
let (_s, recv) = xk_pair(1, 2);
let entry = entry_with_current(recv);
let jitter = entry.rekey_jitter_secs();
assert!(
jitter.abs() <= REKEY_JITTER_SECS,
"jitter within configured bound"
);
// Effective time threshold applies the symmetric jitter.
let effective_after = after_secs.saturating_add_signed(jitter);
// Reproduce the policy's OR predicate directly.
let triggers =
|elapsed: u64, counter: u64| elapsed >= effective_after || counter >= after_messages;
// Time arm: fires at/after the effective threshold, not below it.
assert!(!triggers(effective_after - 1, 0), "below time threshold");
assert!(triggers(effective_after, 0), "at time threshold");
// Counter arm: fires independently of elapsed time.
assert!(!triggers(0, after_messages - 1), "below counter threshold");
assert!(triggers(0, after_messages), "at counter threshold");
}
// The rekey trigger's own threshold arithmetic is tested against the real
// predicate in src/proto/fmp/tests/core.rs, which drives poll_rekey. A test
// here previously reproduced that OR predicate as a local closure and
// asserted against its own copy, so it could not fail for the reason it
// existed: deleting the counter arm from the trigger left it green. Its one
// assertion over real code, that a fresh entry's jitter lies within the
// symmetric bound, is covered over 100 samples by
// test_session_entry_rekey_jitter_in_range in src/node/tests/session.rs.
// Dampening boundary: within `dampening_ms` of the peer's rekey msg1, local
// initiation is suppressed; at/after the window it is not.
+29 -5
View File
@@ -161,13 +161,37 @@ fn rekey_expired_drain_and_trigger_both_fire() {
);
}
/// The send-counter arm of the rekey trigger, pinned at its boundary through
/// the real `poll_rekey` rather than a reimplementation of its predicate.
///
/// Firing at the threshold catches the arm being deleted, its comparison
/// narrowed to `>`, or its comparison inverted. The silence-below half is what
/// this test adds over that: it catches the arm being *widened* below its
/// configured bound. Measured rather than assumed — replacing the bound with
/// `p.counter >= 1` reds exactly one test in the whole library suite, this one,
/// while a bound removed altogether is already caught by the time arm's own
/// negative tests.
///
/// The time arm is held off in both halves — `elapsed_secs` stays 0 against a
/// 100 s threshold with no jitter — so the counter is provably what decides.
#[test]
fn rekey_triggers_on_counter() {
fn rekey_counter_arm_fires_at_threshold_and_is_silent_below() {
let fmp = Fmp::new();
let mut p = peer_snapshot(0x13);
p.counter = 1_000; // == after_messages
let actions = fmp.poll_rekey(vec![p], &cfg());
assert!(matches!(actions[0], ConnAction::InitiateRekey { .. }));
let mut below = peer_snapshot(0x13);
below.counter = 999; // one below after_messages
assert!(
fmp.poll_rekey(vec![below], &cfg()).is_empty(),
"a send counter one below the threshold must not trigger a rekey"
);
let mut at = peer_snapshot(0x13);
at.counter = 1_000; // == after_messages
let actions = fmp.poll_rekey(vec![at], &cfg());
assert!(
matches!(actions[0], ConnAction::InitiateRekey { .. }),
"a send counter at the threshold must trigger a rekey"
);
}
#[test]