swactor/tests/mvp_system/arena_manager_guarantees.rs

267 lines
9.9 KiB
Rust
Raw Normal View History

//! Black-box contract tests for MVP ArenaManager behavior.
//!
//! These tests intentionally know only the public arena-manager surface:
//!
//! - arena boot configuration
//! - lease, cancel, release, quiescence, and shutdown requests in
//! - lease events, rejected requests, released ranges, and faults out
//!
//! They assert the guarantees in
//! `specs/mvp_system/arena_manager_contract.md`.
use mvp_system::arena_manager as arena;
// A small deterministic arena makes overlap, alignment, queueing, and reuse
// proofs easy to inspect. The concrete mmap strategy remains outside the test.
fn arena_config() -> arena::ArenaConfig {
arena::ArenaConfig {
node_id: arena::NodeId(10),
reservation_ceiling: 4096,
base_alignment: 64,
}
}
// Lease requests name size and alignment only. They do not request pointers or
// private allocator slots, which keeps layout authority inside ArenaManager.
fn lease_request(request_id: u64, bytes: u64, alignment: u64) -> arena::LeaseRing {
arena::LeaseRing {
request_id: arena::LeaseRequestId(request_id),
ring_spec: arena::RingSpec {
header_bytes: 128,
data_bytes: bytes,
alignment,
},
}
}
// The harness exposes public lease events and lease snapshots. Tests use those
// snapshots only after a RingLeased event, so private allocator state remains
// unobservable.
fn new_arena() -> arena::ArenaManagerHarness {
arena::ArenaManagerHarness::boot(arena_config()).expect("test arena must boot")
}
// This helper proves two public layouts are disjoint using half-open ranges.
// It is more useful than comparing offsets directly because allocator choice is
// intentionally implementation-defined.
fn assert_non_overlapping(left: &arena::RingLayout, right: &arena::RingLayout) {
let left_range = left.start_offset..left.end_offset;
let right_range = right.start_offset..right.end_offset;
assert!(
left_range.end <= right_range.start || right_range.end <= left_range.start,
"live leases overlap: {left:?} and {right:?}"
);
}
// This proves arena boot creates one stable sparse arena with one reservation
// ceiling, offset-only layouts, and typed boot failure.
#[test]
fn arena_boot_creates_stable_offset_only_layout_domain() {
// Boot a valid arena.
let mut harness = new_arena();
// Lease one ring so the public layout can be inspected.
harness.request(arena::ArenaRequest::LeaseRing(lease_request(1, 512, 64)));
let lease = harness
.events()
.iter()
.find_map(|event| match event {
arena::ArenaEvent::RingLeased { lease } => Some(lease),
_ => None,
})
.expect("valid lease must be granted");
// Layout facts are arena offsets and stay under the reservation ceiling.
assert!(lease.layout.start_offset < arena_config().reservation_ceiling);
assert!(lease.layout.end_offset <= arena_config().reservation_ceiling);
assert!(matches!(lease.layout.pointer, arena::LayoutPointer::NoProcessPointer));
// Boot failure is typed and emits no usable arena.
let failed = arena::ArenaManagerHarness::boot(arena::ArenaConfig {
reservation_ceiling: 0,
..arena_config()
});
assert!(matches!(
failed,
Err(arena::ArenaFault::InvalidReservationCeiling)
));
}
// This proves LeaseRing either leases, queues, or rejects, and that live RingId
// values are unique for the node lifetime.
#[test]
fn lease_requests_grant_queue_or_reject_with_unique_ring_ids() {
// Fill most of the arena with one live lease.
let mut harness = new_arena();
harness.request(arena::ArenaRequest::LeaseRing(lease_request(1, 3072, 64)));
harness.request(arena::ArenaRequest::LeaseRing(lease_request(2, 1024, 64)));
// A satisfiable request under pressure may queue instead of rejecting.
assert!(harness.events().iter().any(|event| {
matches!(
event,
arena::ArenaEvent::RingLeaseQueued {
request_id: arena::LeaseRequestId(2)
}
)
}));
// A request larger than the reservation ceiling must reject.
harness.request(arena::ArenaRequest::LeaseRing(lease_request(3, 8192, 64)));
assert!(harness.events().iter().any(|event| {
matches!(
event,
arena::ArenaEvent::RingLeaseRejected {
request_id: arena::LeaseRequestId(3),
reason: arena::RingLeaseRejection::CannotFitWithinCeiling,
}
)
}));
// Granted RingId values must be unique among all live leases.
let ids = harness
.live_leases()
.iter()
.map(|lease| lease.ring_id)
.collect::<std::collections::BTreeSet<_>>();
assert_eq!(ids.len(), harness.live_leases().len());
}
// This proves live leases are non-overlapping, in-bounds, aligned, and stable
// for the lease lifetime.
#[test]
fn live_layouts_are_non_overlapping_aligned_in_bounds_and_stable() {
// Lease two rings with explicit alignment requirements.
let mut harness = new_arena();
harness.request(arena::ArenaRequest::LeaseRing(lease_request(1, 512, 64)));
harness.request(arena::ArenaRequest::LeaseRing(lease_request(2, 512, 128)));
// Read the public lease snapshots.
let leases = harness.live_leases().to_vec();
assert_eq!(leases.len(), 2);
// Prove non-overlap and in-bounds without constraining allocator placement.
assert_non_overlapping(&leases[0].layout, &leases[1].layout);
for lease in &leases {
assert!(lease.layout.end_offset <= arena_config().reservation_ceiling);
assert_eq!(lease.layout.start_offset % lease.requested_alignment, 0);
}
// Re-observing the same live lease must not change offsets.
let before = leases[0].layout.clone();
let after = harness
.lookup_lease(leases[0].ring_id)
.expect("live lease must be lookupable")
.layout
.clone();
assert_eq!(after, before);
}
// This proves CancelLease removes queued work and suppresses later hot-path
// installation, including a fresh lease that races with cancellation.
#[test]
fn cancelled_queued_lease_never_installs_hot_path_state() {
// Fill the arena and queue a second satisfiable lease.
let mut harness = new_arena();
harness.request(arena::ArenaRequest::LeaseRing(lease_request(1, 3072, 64)));
harness.request(arena::ArenaRequest::LeaseRing(lease_request(2, 1024, 64)));
// Cancel the queued request before it is leased.
harness.request(arena::ArenaRequest::CancelLease {
request_id: arena::LeaseRequestId(2),
});
// Releasing pressure must not install worker or pump state for the canceled
// request.
let live = harness.live_leases()[0].ring_id;
harness.request(arena::ArenaRequest::ReleaseRing {
ring_id: live,
proof: arena::QuiescenceProof::verified(),
});
assert!(!harness.commands().iter().any(|command| {
matches!(
command,
arena::ArenaCommand::InstallWorkerOrPumpState {
request_id: arena::LeaseRequestId(2),
..
}
)
}));
// If a fresh lease was produced during the race, it must be released instead
// of becoming hot-path state.
assert!(harness.events().iter().any(|event| {
matches!(
event,
arena::ArenaEvent::CancelledFreshLeaseReleased {
request_id: arena::LeaseRequestId(2)
}
)
}));
}
// This proves ranges are released only with quiescence proof, are not reused
// while live work owns them, and may be reused after release.
#[test]
fn release_requires_quiescence_and_reuse_happens_only_after_release() {
// Lease one ring and record its range.
let mut harness = new_arena();
harness.request(arena::ArenaRequest::LeaseRing(lease_request(1, 1024, 64)));
let first = harness.live_leases()[0].clone();
// Release without proof must reject and keep the range live.
harness.request(arena::ArenaRequest::ReleaseRing {
ring_id: first.ring_id,
proof: arena::QuiescenceProof::missing(),
});
assert!(harness.lookup_lease(first.ring_id).is_some());
// A second lease while the first is live must not overlap the first range.
harness.request(arena::ArenaRequest::LeaseRing(lease_request(2, 1024, 64)));
let second = harness
.live_leases()
.iter()
.find(|lease| lease.ring_id != first.ring_id)
.expect("second live lease must exist")
.clone();
assert_non_overlapping(&first.layout, &second.layout);
// Verified quiescence allows release, after which reuse is legal.
harness.request(arena::ArenaRequest::ReleaseRing {
ring_id: first.ring_id,
proof: arena::QuiescenceProof::verified(),
});
harness.request(arena::ArenaRequest::LeaseRing(lease_request(3, 1024, 64)));
assert!(harness.events().iter().any(|event| {
matches!(event, arena::ArenaEvent::RingLeased { .. })
}));
}
// This proves shutdown rejects new leases, preserves live lease records, and
// does not release live ranges without quiescence proof.
#[test]
fn shutdown_rejects_new_leases_without_corrupting_live_records() {
// Create a live lease before shutdown.
let mut harness = new_arena();
harness.request(arena::ArenaRequest::LeaseRing(lease_request(1, 512, 64)));
let live_before = harness.live_leases().to_vec();
// Shut the arena down.
harness.request(arena::ArenaRequest::Shutdown);
// New leases are rejected after shutdown.
harness.request(arena::ArenaRequest::LeaseRing(lease_request(2, 512, 64)));
assert!(harness.events().iter().any(|event| {
matches!(
event,
arena::ArenaEvent::RingLeaseRejected {
request_id: arena::LeaseRequestId(2),
reason: arena::RingLeaseRejection::ArenaShuttingDown,
}
)
}));
// Existing live lease records remain intact until proof-backed release.
assert_eq!(harness.live_leases(), live_before.as_slice());
}