#![cfg(feature = "draft14")]
use moqtap_client::draft14::session::request_id::*;
#[test]
fn client_allocates_even_ids() {
let mut alloc = RequestIdAllocator::new(Role::Client);
alloc.update_max(10).unwrap();
let id0 = alloc.allocate().expect("allocate 0");
let id2 = alloc.allocate().expect("allocate 2");
let id4 = alloc.allocate().expect("allocate 4");
assert_eq!(id0.into_inner(), 0);
assert_eq!(id2.into_inner(), 2);
assert_eq!(id4.into_inner(), 4);
}
#[test]
fn server_allocates_odd_ids() {
let mut alloc = RequestIdAllocator::new(Role::Server);
alloc.update_max(10).unwrap();
let id1 = alloc.allocate().expect("allocate 1");
let id3 = alloc.allocate().expect("allocate 3");
let id5 = alloc.allocate().expect("allocate 5");
assert_eq!(id1.into_inner(), 1);
assert_eq!(id3.into_inner(), 3);
assert_eq!(id5.into_inner(), 5);
}
#[test]
fn allocate_respects_max_request_id() {
let mut alloc = RequestIdAllocator::new(Role::Client);
alloc.update_max(4).unwrap();
alloc.allocate().expect("allocate 0");
alloc.allocate().expect("allocate 2");
alloc.allocate().expect("allocate 4");
let result = alloc.allocate();
assert!(result.is_err(), "allocation beyond max should be blocked");
}
#[test]
fn allocate_blocked_when_default_max_is_zero() {
let alloc = &mut RequestIdAllocator::new(Role::Client);
let result = alloc.allocate();
assert!(result.is_err(), "allocation should be blocked when max is 0 (default)");
}
#[test]
fn allocate_unblocked_after_max_increase() {
let mut alloc = RequestIdAllocator::new(Role::Client);
assert!(alloc.is_blocked(), "should be blocked at default max");
alloc.update_max(2).unwrap();
assert!(!alloc.is_blocked(), "should be unblocked after max increase");
let id = alloc.allocate().expect("should allocate after unblock");
assert_eq!(id.into_inner(), 0);
}
#[test]
fn max_request_id_can_increase() {
let mut alloc = RequestIdAllocator::new(Role::Client);
let result = alloc.update_max(10);
assert!(result.is_ok(), "increasing max should succeed");
assert_eq!(alloc.max_id(), 10);
}
#[test]
fn max_request_id_cannot_decrease() {
let mut alloc = RequestIdAllocator::new(Role::Client);
alloc.update_max(10).unwrap();
let result = alloc.update_max(5);
assert!(result.is_err(), "decreasing max should fail");
match result.unwrap_err() {
RequestIdError::Decreased(was, got) => {
assert_eq!(was, 10);
assert_eq!(got, 5);
}
other => panic!("expected Decreased error, got: {other:?}"),
}
}
#[test]
fn max_request_id_cannot_stay_same() {
let mut alloc = RequestIdAllocator::new(Role::Client);
alloc.update_max(10).unwrap();
let result = alloc.update_max(10);
assert!(result.is_err(), "setting max to equal value should fail (must strictly increase)");
match result.unwrap_err() {
RequestIdError::Decreased(was, got) => {
assert_eq!(was, 10);
assert_eq!(got, 10);
}
other => panic!("expected Decreased error, got: {other:?}"),
}
}
#[test]
fn max_request_id_default_is_zero() {
let alloc = RequestIdAllocator::new(Role::Server);
assert_eq!(alloc.max_id(), 0);
}
#[test]
fn client_validates_peer_sends_odd() {
let mut alloc = RequestIdAllocator::new(Role::Client);
alloc.update_max(10).unwrap();
let result = alloc.validate_peer_id(1);
assert!(result.is_ok(), "client should accept odd peer id: {result:?}");
}
#[test]
fn client_rejects_peer_even_id() {
let mut alloc = RequestIdAllocator::new(Role::Client);
alloc.update_max(10).unwrap();
let result = alloc.validate_peer_id(2);
assert!(result.is_err(), "client should reject even peer id");
match result.unwrap_err() {
RequestIdError::WrongParity(id, _role) => {
assert_eq!(id, 2);
}
other => panic!("expected WrongParity error, got: {other:?}"),
}
}
#[test]
fn server_rejects_peer_odd_id() {
let mut alloc = RequestIdAllocator::new(Role::Server);
alloc.update_max(10).unwrap();
let result = alloc.validate_peer_id(1);
assert!(result.is_err(), "server should reject odd peer id");
match result.unwrap_err() {
RequestIdError::WrongParity(id, _role) => {
assert_eq!(id, 1);
}
other => panic!("expected WrongParity error, got: {other:?}"),
}
}
#[test]
fn validate_peer_id_exceeds_max() {
let mut alloc = RequestIdAllocator::new(Role::Client);
alloc.update_max(10).unwrap();
let result = alloc.validate_peer_id(101);
assert!(result.is_err(), "peer id exceeding max should fail");
match result.unwrap_err() {
RequestIdError::ExceedsMax(id, max) => {
assert_eq!(id, 101);
assert_eq!(max, 10);
}
other => panic!("expected ExceedsMax error, got: {other:?}"),
}
}
#[test]
fn server_validates_peer_sends_even() {
let mut alloc = RequestIdAllocator::new(Role::Server);
alloc.update_max(10).unwrap();
let result = alloc.validate_peer_id(2);
assert!(result.is_ok(), "server should accept even peer id: {result:?}");
}
#[test]
fn is_blocked_reflects_capacity() {
let mut alloc = RequestIdAllocator::new(Role::Client);
assert!(alloc.is_blocked(), "should be blocked at default max=0");
alloc.update_max(0).ok(); assert!(alloc.is_blocked(), "should still be blocked");
alloc.update_max(2).unwrap();
assert!(!alloc.is_blocked(), "should be unblocked after max increase to 2");
alloc.allocate().unwrap(); alloc.allocate().unwrap(); assert!(alloc.is_blocked(), "should be blocked after exhausting IDs up to max");
}