From a4cb5d6f3e579e989c124a8c2be5fead040422bc Mon Sep 17 00:00:00 2001 From: Leynos Date: Mon, 7 Jul 2025 21:14:06 +0100 Subject: [PATCH 1/2] Add scheduler boundary tests --- tests/connection_actor.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/connection_actor.rs b/tests/connection_actor.rs index e3ac79c2..c4dd6fe5 100644 --- a/tests/connection_actor.rs +++ b/tests/connection_actor.rs @@ -89,6 +89,8 @@ enum Priority { #[rstest] #[case(vec![Priority::High, Priority::High, Priority::High, Priority::Low, Priority::Low])] #[case(vec![Priority::Low, Priority::Low, Priority::High, Priority::High, Priority::High])] +#[case(vec![Priority::High, Priority::High, Priority::High])] +#[case(vec![Priority::Low, Priority::Low, Priority::Low])] #[tokio::test] async fn fairness_disabled_processes_all_high_first( #[case] order: Vec, @@ -101,9 +103,13 @@ async fn fairness_disabled_processes_all_high_first( time_slice: None, }; - let mut highs = 1..=3; - let mut lows = 4..=5; - for priority in order { + let high_count = order.iter().filter(|p| matches!(p, Priority::High)).count(); + let low_count = order.len() - high_count; + + let mut highs = (1u8..).take(high_count); + let start_low = u8::try_from(high_count).expect("too many high frames") + 1; + let mut lows = (start_low..).take(low_count); + for priority in &order { match priority { Priority::High => { let n = highs.next().expect("ran out of high-priority frames"); @@ -123,7 +129,11 @@ async fn fairness_disabled_processes_all_high_first( actor.set_fairness(fairness); let mut out = Vec::new(); actor.run(&mut out).await.expect("actor run failed"); - assert_eq!(out, vec![1, 2, 3, 4, 5]); + let high_end = u8::try_from(high_count).expect("too many high frames"); + let expected: Vec = (1..=high_end) + .chain(high_end + 1..=u8::try_from(order.len()).expect("order length")) + .collect(); + assert_eq!(out, expected); } #[rstest] From ebfe9449bcdf0d248d8ba2a2ab49a5897a5e62a0 Mon Sep 17 00:00:00 2001 From: Leynos Date: Mon, 7 Jul 2025 22:10:05 +0100 Subject: [PATCH 2/2] Add boundary scheduler tests --- tests/connection_actor.rs | 63 +++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/tests/connection_actor.rs b/tests/connection_actor.rs index c4dd6fe5..c23403d8 100644 --- a/tests/connection_actor.rs +++ b/tests/connection_actor.rs @@ -86,13 +86,46 @@ enum Priority { Low, } +/// Push frames in the given priority order and return the expected output +/// sequence when fairness is disabled. +async fn queue_frames( + order: &[Priority], + handle: &wireframe::push::PushHandle, + high_count: usize, +) -> Vec { + let mut next_high = 1u8; + let mut next_low = u8::try_from(high_count).expect("too many high frames") + 1; + + let mut highs = Vec::new(); + let mut lows = Vec::new(); + + for priority in order { + match priority { + Priority::High => { + let msg = format!("failed to push high-priority frame {next_high}"); + handle.push_high_priority(next_high).await.expect(&msg); + highs.push(next_high); + next_high += 1; + } + Priority::Low => { + let msg = format!("failed to push low-priority frame {next_low}"); + handle.push_low_priority(next_low).await.expect(&msg); + lows.push(next_low); + next_low += 1; + } + } + } + + highs.into_iter().chain(lows.into_iter()).collect() +} + #[rstest] #[case(vec![Priority::High, Priority::High, Priority::High, Priority::Low, Priority::Low])] #[case(vec![Priority::Low, Priority::Low, Priority::High, Priority::High, Priority::High])] -#[case(vec![Priority::High, Priority::High, Priority::High])] -#[case(vec![Priority::Low, Priority::Low, Priority::Low])] +#[case(vec![Priority::High; 3])] +#[case(vec![Priority::Low; 3])] #[tokio::test] -async fn fairness_disabled_processes_all_high_first( +async fn processes_all_priorities_in_order( #[case] order: Vec, queues: (PushQueues, wireframe::push::PushHandle), shutdown_token: CancellationToken, @@ -104,35 +137,13 @@ async fn fairness_disabled_processes_all_high_first( }; let high_count = order.iter().filter(|p| matches!(p, Priority::High)).count(); - let low_count = order.len() - high_count; - - let mut highs = (1u8..).take(high_count); - let start_low = u8::try_from(high_count).expect("too many high frames") + 1; - let mut lows = (start_low..).take(low_count); - for priority in &order { - match priority { - Priority::High => { - let n = highs.next().expect("ran out of high-priority frames"); - let msg = format!("failed to push high-priority frame {n}"); - handle.push_high_priority(n).await.expect(&msg); - } - Priority::Low => { - let n = lows.next().expect("ran out of low-priority frames"); - let msg = format!("failed to push low-priority frame {n}"); - handle.push_low_priority(n).await.expect(&msg); - } - } - } + let expected = queue_frames(&order, &handle, high_count).await; let mut actor: ConnectionActor<_, ()> = ConnectionActor::new(queues, handle, None, shutdown_token); actor.set_fairness(fairness); let mut out = Vec::new(); actor.run(&mut out).await.expect("actor run failed"); - let high_end = u8::try_from(high_count).expect("too many high frames"); - let expected: Vec = (1..=high_end) - .chain(high_end + 1..=u8::try_from(order.len()).expect("order length")) - .collect(); assert_eq!(out, expected); }