Tests kill mutation survivors: each owned-name site is pinned alone, the member range below the route's is accepted, a challenge near the frame bound is answered; accept errors share one backoff
Builds. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
9173a0e8e6
commit
b379fbd700
2 changed files with 56 additions and 12 deletions
|
|
@ -2412,8 +2412,10 @@ nodes = ["yggdrasil"]
|
|||
// Overlapping the route's own private range, in either direction.
|
||||
assert!(start("18835").is_err());
|
||||
assert!(start("18825").is_err());
|
||||
// Adjacent but disjoint is fine.
|
||||
// Adjacent but disjoint is fine, above the route's range or below it.
|
||||
assert!(start("18840").is_ok());
|
||||
assert!(start("18822").is_ok());
|
||||
assert!(start("18823").is_err());
|
||||
// Zero, and a width that overflows u16.
|
||||
assert!(start("0").is_err());
|
||||
assert!(start("65530").is_err());
|
||||
|
|
@ -2473,18 +2475,37 @@ nodes = ["yggdrasil"]
|
|||
assert!(OperatorBinding::parse(&as_environment("UNOWNED_NAME")).is_ok());
|
||||
assert!(OperatorBinding::parse(&as_secret("UNOWNED_NAME")).is_ok());
|
||||
for name in owned {
|
||||
// Refused when the binding is parsed...
|
||||
assert!(
|
||||
OperatorBinding::parse(&as_environment(name))
|
||||
.and_then(|binding| binding.admit(&recipe))
|
||||
.is_err(),
|
||||
"{name} accepted as environment"
|
||||
OperatorBinding::parse(&as_environment(name)).is_err(),
|
||||
"{name} accepted as environment at parse"
|
||||
);
|
||||
assert!(
|
||||
OperatorBinding::parse(&as_secret(name))
|
||||
.and_then(|binding| binding.admit(&recipe))
|
||||
.is_err(),
|
||||
"{name} accepted as a secret file"
|
||||
OperatorBinding::parse(&as_secret(name)).is_err(),
|
||||
"{name} accepted as a secret file at parse"
|
||||
);
|
||||
// ...and again at admission, for a binding that did not come
|
||||
// through parse. Each site reads the one list.
|
||||
for secret in [false, true] {
|
||||
let mut binding = OperatorBinding::parse(BINDING).unwrap();
|
||||
let WorkloadBinding::SystemdTransient(workload) = &mut binding.workload else {
|
||||
panic!("the fixture is a systemd workload");
|
||||
};
|
||||
if secret {
|
||||
workload.secret_files.insert(name.into(), "/etc/gamecult/test-service/other.cc".into());
|
||||
} else {
|
||||
workload.environment.insert(name.into(), "forged".into());
|
||||
}
|
||||
assert!(
|
||||
binding.workload.validate_launch_environment().is_err(),
|
||||
"{name} (secret: {secret}) accepted by the binding check"
|
||||
);
|
||||
let error = binding.admit(&recipe).unwrap_err().to_string();
|
||||
assert!(
|
||||
error.contains("Idunn-owned launch environment"),
|
||||
"{name} (secret: {secret}) accepted by the launch-input check: {error}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -955,9 +955,8 @@ impl PresenceAcceptor {
|
|||
let _ = connection.set_nonblocking(false);
|
||||
let _ = self.answer(connection);
|
||||
}
|
||||
Err(error) if error.kind() == io::ErrorKind::WouldBlock => {
|
||||
thread::sleep(Duration::from_millis(10));
|
||||
}
|
||||
// An idle non-blocking accept is an error too; every one waits
|
||||
// and tries again.
|
||||
Err(_) => thread::sleep(ACCEPT_BACKOFF),
|
||||
}
|
||||
}
|
||||
|
|
@ -2229,6 +2228,30 @@ mod tests {
|
|||
serving.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_challenge_up_to_the_frame_bound_is_answered_and_one_past_it_is_not() {
|
||||
let fx = fixture(false);
|
||||
let (address, halt, serving) = serve_presence(&fx);
|
||||
// A request far larger than a few KiB, well inside the 1 MiB bound.
|
||||
let request = CultNetMessage::SnapshotRequest {
|
||||
message_id: "large".into(),
|
||||
schema_ids: Some(vec![GAMECULT_RUNTIME_PRESENCE_HEALTH_SCHEMA.into()]),
|
||||
record_keys: Some((0..300).map(|index| format!("{index:0>40}")).collect()),
|
||||
};
|
||||
let payload =
|
||||
encode_cultnet_message_to_vec(&request, CultNetWireContract::CultNetSchemaV0).unwrap();
|
||||
assert!(payload.len() > 10_000 && payload.len() < CHALLENGE_MAX_BYTES);
|
||||
assert!(request_tcp_snapshot(address, &payload).is_ok());
|
||||
// One byte past the bound is closed unanswered.
|
||||
let past = (CHALLENGE_MAX_BYTES as u32 + 1).to_be_bytes();
|
||||
assert_eq!(past[0], CHALLENGE_FIRST_BYTE);
|
||||
let mut oversized = TcpStream::connect(address).unwrap();
|
||||
oversized.write_all(&past).unwrap();
|
||||
assert!(closed_within(&mut oversized, Duration::from_secs(3)), "an oversized frame was read");
|
||||
halt.store(true, Ordering::SeqCst);
|
||||
serving.join().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn an_idle_peer_holds_the_acceptor_for_the_presence_deadline_and_no_longer() {
|
||||
let fx = fixture(false);
|
||||
|
|
|
|||
Loading…
Reference in a new issue