test(host): close Row 9 fanout partition

This commit is contained in:
2026-08-21 19:55:41 -04:00
parent 956534f63c
commit 7b118272b0
+94 -9
View File
@@ -1038,8 +1038,15 @@ mod tests {
));
}
#[test]
fn eligible_late_arrival_is_positively_captured() {
#[derive(Clone, Copy)]
enum Row9Scenario {
MusicOnly,
DifferentDeviceMicrophone,
SameDeviceMicrophone,
TaintedMonitor,
}
fn assert_row_9_late_arrival(scenario: Row9Scenario, expected_reason: Option<&str>) {
let mut graph = Graph::new();
let sink = graph.native_virtual_node("pixelpass_capture_test", MediaRole::Sink, 43);
graph.port_on_channel(sink, PortDirection::In, false, Some("FL"));
@@ -1049,17 +1056,95 @@ mod tests {
drive(&mut controller, &graph, &mut links);
assert!(links.held.is_empty());
let late = graph.app_node("late", MediaRole::StreamOutput, 44);
graph.port_on_channel(late, PortDirection::Out, false, Some("FL"));
graph.port_on_channel(late, PortDirection::Out, false, Some("FR"));
let firefox_pid = 11_114;
let firefox = match scenario {
Row9Scenario::MusicOnly => {
graph.app_node("firefox-music", MediaRole::StreamOutput, firefox_pid)
}
Row9Scenario::DifferentDeviceMicrophone => {
let speakers = graph.device_node_on("speakers", MediaRole::Sink, GlobalId(700));
let microphone =
graph.device_node_on("usb-microphone", MediaRole::Source, GlobalId(701));
let call = graph.peerspeak_node("call", 7);
let firefox_in =
graph.app_node("firefox-microphone", MediaRole::StreamInput, firefox_pid);
graph.link(call, speakers);
graph.link(microphone, firefox_in);
graph.app_node("firefox-audio", MediaRole::StreamOutput, firefox_pid)
}
Row9Scenario::SameDeviceMicrophone => {
let device = GlobalId(700);
let speakers = graph.device_node_on("headset-output", MediaRole::Sink, device);
let microphone =
graph.device_node_on("headset-microphone", MediaRole::Source, device);
let call = graph.peerspeak_node("call", 7);
let firefox_in =
graph.app_node("firefox-microphone", MediaRole::StreamInput, firefox_pid);
graph.link(call, speakers);
graph.link(microphone, firefox_in);
graph.app_node("firefox-audio", MediaRole::StreamOutput, firefox_pid)
}
Row9Scenario::TaintedMonitor => {
let speakers = graph.device_node("speakers", MediaRole::Sink);
let call = graph.peerspeak_node("call", 7);
let firefox_in =
graph.app_node("firefox-monitor", MediaRole::StreamInput, firefox_pid);
graph.link(call, speakers);
graph.link(speakers, firefox_in);
graph.app_node("firefox-audio", MediaRole::StreamOutput, firefox_pid)
}
};
graph.port_on_channel(firefox, PortDirection::Out, false, Some("FL"));
graph.port_on_channel(firefox, PortDirection::Out, false, Some("FR"));
drive(&mut controller, &graph, &mut links);
assert_eq!(links.creates, 2);
assert_eq!(
controller.states()[&late.serial],
StreamCaptureState::Captured
match expected_reason {
None => {
assert_eq!(links.creates, 2, "both stereo links must be created");
assert_eq!(links.held.len(), 2);
assert_eq!(
controller.states()[&firefox.serial],
StreamCaptureState::Captured
);
}
Some(expected_reason) => {
assert_eq!(links.creates, 0, "an excluded stream must never be linked");
assert!(links.held.is_empty());
let StreamCaptureState::Excluded { reason } = controller.states()[&firefox.serial]
else {
panic!("the late Firefox stream must be excluded");
};
assert_eq!(reason.code(), expected_reason);
}
}
drive(&mut controller, &graph, &mut links);
assert_eq!(links.creates, if expected_reason.is_none() { 2 } else { 0 });
}
#[test]
fn row_9a_music_only_late_arrival_is_positively_captured() {
assert_row_9_late_arrival(Row9Scenario::MusicOnly, None);
}
#[test]
fn row_9b_different_device_microphone_late_arrival_is_positively_captured() {
assert_row_9_late_arrival(Row9Scenario::DifferentDeviceMicrophone, None);
}
#[test]
fn row_9c_same_device_microphone_late_arrival_is_never_linked() {
assert_row_9_late_arrival(
Row9Scenario::SameDeviceMicrophone,
Some("tainted-owner-bridge"),
);
}
#[test]
fn row_9d_tainted_monitor_late_arrival_is_never_linked() {
assert_row_9_late_arrival(Row9Scenario::TaintedMonitor, Some("tainted-owner-bridge"));
}
#[test]
fn configured_but_unvalidated_aec_gates_every_mutation() {
let (graph, app, sink, _) = stereo_graph();