swactor/tests/mailbox_tests.rs

227 lines
4.4 KiB
Rust
Raw Normal View History

use swactor::worker::Mailbox;
// ── Basic operations ──
#[test]
fn push_and_pop() {
let mut mb = Mailbox::new(10);
mb.push(42i32);
assert_eq!(mb.pop(), Some(42));
}
#[test]
fn fifo_ordering() {
let mut mb = Mailbox::new(10);
mb.push(1);
mb.push(2);
mb.push(3);
assert_eq!(mb.pop(), Some(1));
assert_eq!(mb.pop(), Some(2));
assert_eq!(mb.pop(), Some(3));
}
#[test]
fn pop_empty() {
let mut mb: Mailbox<i32> = Mailbox::new(10);
assert_eq!(mb.pop(), None);
}
#[test]
fn multiple_messages() {
let mut mb = Mailbox::new(10);
for i in 0..100 {
mb.push(i);
}
for i in 0..100 {
assert_eq!(mb.pop(), Some(i));
}
assert_eq!(mb.pop(), None);
}
#[test]
fn interleaved_push_pop() {
let mut mb = Mailbox::new(10);
mb.push(1);
mb.push(2);
assert_eq!(mb.pop(), Some(1));
mb.push(3);
assert_eq!(mb.pop(), Some(2));
assert_eq!(mb.pop(), Some(3));
assert_eq!(mb.pop(), None);
}
// ── Drain count / watermark logic ──
#[test]
fn drain_count_empty() {
let mb: Mailbox<i32> = Mailbox::new(10);
assert_eq!(mb.drain_count(), 0);
}
#[test]
fn drain_count_below_waterlevel() {
let mut mb = Mailbox::new(10);
for i in 0..5 {
mb.push(i);
}
// 5 < 10 (default waterlevel) → process all
assert_eq!(mb.drain_count(), 5);
}
#[test]
fn drain_count_at_waterlevel() {
let mut mb = Mailbox::new(10);
for i in 0..10 {
mb.push(i);
}
// 10 >= 10 → process half → 5
assert_eq!(mb.drain_count(), 5);
}
#[test]
fn drain_count_above_waterlevel() {
let mut mb = Mailbox::new(10);
for i in 0..20 {
mb.push(i);
}
// 20 >= 10 → 20 >> 1 = 10
assert_eq!(mb.drain_count(), 10);
}
#[test]
fn drain_count_one_message() {
let mut mb = Mailbox::new(10);
mb.push(1i32);
// 1 < 10 → process all → 1
assert_eq!(mb.drain_count(), 1);
}
#[test]
fn drain_count_just_below_waterlevel() {
let mut mb = Mailbox::new(10);
for i in 0..9 {
mb.push(i);
}
// 9 < 10 → process all → 9
assert_eq!(mb.drain_count(), 9);
}
#[test]
fn drain_count_large() {
let mut mb = Mailbox::new(10);
for i in 0..1000 {
mb.push(i);
}
// 1000 >= 10 → 1000 >> 1 = 500
assert_eq!(mb.drain_count(), 500);
}
#[test]
fn drain_count_custom_waterlevel() {
let mut mb = Mailbox::new(4);
for i in 0..3 {
mb.push(i);
}
// 3 < 4 → process all → 3
assert_eq!(mb.drain_count(), 3);
mb.push(99);
// 4 >= 4 → 4 >> 1 = 2
assert_eq!(mb.drain_count(), 2);
}
#[test]
fn drain_count_updates_after_pop() {
let mut mb = Mailbox::new(10);
for i in 0..20 {
mb.push(i);
}
// 20 >= 10 → 10
assert_eq!(mb.drain_count(), 10);
// pop 15, leaving 5
for _ in 0..15 {
mb.pop();
}
// 5 < 10 → process all → 5
assert_eq!(mb.drain_count(), 5);
}
// ── Properties ──
#[test]
fn len_tracks_pushes() {
let mut mb = Mailbox::new(10);
assert_eq!(mb.len(), 0);
mb.push(1);
assert_eq!(mb.len(), 1);
mb.push(2);
assert_eq!(mb.len(), 2);
mb.push(3);
assert_eq!(mb.len(), 3);
}
#[test]
fn len_tracks_pops() {
let mut mb = Mailbox::new(10);
mb.push(1);
mb.push(2);
mb.push(3);
assert_eq!(mb.len(), 3);
mb.pop();
assert_eq!(mb.len(), 2);
mb.pop();
assert_eq!(mb.len(), 1);
mb.pop();
assert_eq!(mb.len(), 0);
}
#[test]
fn is_empty_on_new() {
let mb: Mailbox<i32> = Mailbox::new(10);
assert!(mb.is_empty());
}
#[test]
fn is_empty_after_drain() {
let mut mb = Mailbox::new(10);
mb.push(1);
mb.push(2);
mb.push(3);
assert!(!mb.is_empty());
mb.pop();
mb.pop();
mb.pop();
assert!(mb.is_empty());
}
// ── Type tests ──
#[test]
fn works_with_primitive_types() {
let mut mb_i32 = Mailbox::new(10);
mb_i32.push(42i32);
assert_eq!(mb_i32.pop(), Some(42));
let mut mb_string = Mailbox::new(10);
mb_string.push(String::from("hello"));
assert_eq!(mb_string.pop(), Some(String::from("hello")));
}
#[test]
fn works_with_custom_structs() {
#[derive(Debug, Clone, PartialEq)]
struct MyMsg {
id: u64,
payload: String,
}
let mut mb = Mailbox::new(10);
let msg = MyMsg {
id: 1,
payload: "test".into(),
};
mb.push(msg.clone());
assert_eq!(mb.pop(), Some(msg));
}