Merge pull request #147 from ChunMinChang/fix-device-changed-test

Fix device-changed test for duplex stream when we have only one input and multiple output
This commit is contained in:
Chun-Min Chang 2022-02-25 08:26:12 -08:00 коммит произвёл GitHub
Родитель 87b351b035 28b89399e7
Коммит 0a35299b99
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 66 добавлений и 49 удалений

Просмотреть файл

@ -1,6 +1,6 @@
use super::utils::{
test_get_all_devices, test_get_all_onwed_devices, test_get_default_device,
test_get_drift_compensations, test_get_master_device, Scope,
test_get_drift_compensations, test_get_master_device, DeviceFilter, Scope,
};
use super::*;
@ -42,7 +42,7 @@ fn test_aggregate_set_sub_devices_for_unknown_devices() {
// application and print out the sub devices of them!
#[test]
fn test_aggregate_get_sub_devices() {
let devices = test_get_all_devices();
let devices = test_get_all_devices(DeviceFilter::ExcludeCubebAggregate);
for device in devices {
// `AggregateDevice::get_sub_devices(device)` will return a single-element vector
// containing `device` itself if it's not an aggregate device. This test assumes devices
@ -108,7 +108,7 @@ fn test_aggregate_create_blank_device() {
// TODO: Test this when there is no available devices.
let plugin = AggregateDevice::get_system_plugin_id().unwrap();
let device = AggregateDevice::create_blank_device_sync(plugin).unwrap();
let devices = test_get_all_devices();
let devices = test_get_all_devices(DeviceFilter::IncludeCubebAggregate);
let device = devices.into_iter().find(|dev| dev == &device).unwrap();
let uid = get_device_global_uid(device).unwrap().into_string();
assert!(uid.contains(PRIVATE_AGGREGATE_DEVICE_NAME));

Просмотреть файл

@ -3,7 +3,7 @@ use super::utils::{
test_device_channels_in_scope, test_device_in_scope, test_get_all_devices,
test_get_default_audiounit, test_get_default_device, test_get_default_raw_stream,
test_get_default_source_name, test_get_devices_in_scope, test_get_raw_context,
ComponentSubType, PropertyScope, Scope,
ComponentSubType, DeviceFilter, PropertyScope, Scope,
};
use super::*;
@ -1523,7 +1523,7 @@ fn test_get_devices_of_type() {
let input_devices = audiounit_get_devices_of_type(DeviceType::INPUT);
let output_devices = audiounit_get_devices_of_type(DeviceType::OUTPUT);
let mut expected_all = test_get_all_devices();
let mut expected_all = test_get_all_devices(DeviceFilter::ExcludeCubebAggregate);
expected_all.sort();
assert_eq!(all_devices, expected_all);
for device in all_devices.iter() {

Просмотреть файл

@ -319,23 +319,29 @@ fn test_register_device_changed_callback_to_check_default_device_changed_duplex(
fn test_register_device_changed_callback_to_check_default_device_changed(stm_type: StreamType) {
println!("NOTICE: The test will hang if the default input or output is an aggregate device.\nWe will fix this later.");
let input_devices = test_get_devices_in_scope(Scope::Input).len();
let output_devices = test_get_devices_in_scope(Scope::Output).len();
let input_available = input_devices >= 2;
let output_available = output_devices >= 2;
let run_available = match stm_type {
StreamType::INPUT => input_available,
StreamType::OUTPUT => output_available,
StreamType::DUPLEX => input_available | output_available,
_ => {
println!("Only test input, output, or duplex stream!");
return;
let inputs = if stm_type.contains(StreamType::INPUT) {
let devices = test_get_devices_in_scope(Scope::Input).len();
if devices >= 2 {
Some(devices)
} else {
None
}
} else {
None
};
if !run_available {
let outputs = if stm_type.contains(StreamType::OUTPUT) {
let devices = test_get_devices_in_scope(Scope::Output).len();
if devices >= 2 {
Some(devices)
} else {
None
}
} else {
None
};
if inputs.is_none() && outputs.is_none() {
println!("No enough devices to run the test!");
return;
}
@ -344,20 +350,6 @@ fn test_register_device_changed_callback_to_check_default_device_changed(stm_typ
let also_changed_count = Arc::clone(&changed_count);
let mtx_ptr = also_changed_count.as_ref() as *const Mutex<u32>;
let input_count = if stm_type.contains(StreamType::INPUT) {
input_devices
} else {
0
};
let output_count = if stm_type.contains(StreamType::OUTPUT) {
output_devices
} else {
0
};
let mut input_device_switcher = TestDeviceSwitcher::new(Scope::Input);
let mut output_device_switcher = TestDeviceSwitcher::new(Scope::Output);
test_get_stream_with_device_changed_callback(
"stream: test callback for default device changed",
stm_type,
@ -374,22 +366,28 @@ fn test_register_device_changed_callback_to_check_default_device_changed(stm_typ
let mut changed_watcher = Watcher::new(&changed_count);
for _ in 0..input_count {
// While the stream is re-initializing for the default device switch,
// switching for the default device again will be ignored.
while stream.switching_device.load(atomic::Ordering::SeqCst) {}
changed_watcher.prepare();
input_device_switcher.next();
changed_watcher.wait_for_change();
if let Some(devices) = inputs {
let mut device_switcher = TestDeviceSwitcher::new(Scope::Input);
for _ in 0..devices {
// While the stream is re-initializing for the default device switch,
// switching for the default device again will be ignored.
while stream.switching_device.load(atomic::Ordering::SeqCst) {}
changed_watcher.prepare();
device_switcher.next();
changed_watcher.wait_for_change();
}
}
for _ in 0..output_count {
// While the stream is re-initializing for the default device switch,
// switching for the default device again will be ignored.
while stream.switching_device.load(atomic::Ordering::SeqCst) {}
changed_watcher.prepare();
output_device_switcher.next();
changed_watcher.wait_for_change();
if let Some(devices) = outputs {
let mut device_switcher = TestDeviceSwitcher::new(Scope::Output);
for _ in 0..devices {
// While the stream is re-initializing for the default device switch,
// switching for the default device again will be ignored.
while stream.switching_device.load(atomic::Ordering::SeqCst) {}
changed_watcher.prepare();
device_switcher.next();
changed_watcher.wait_for_change();
}
}
},
);

Просмотреть файл

@ -243,7 +243,11 @@ fn u32_to_string(data: u32) -> String {
String::from_utf8_lossy(&buffer).to_string()
}
pub fn test_get_all_devices() -> Vec<AudioObjectID> {
pub enum DeviceFilter {
ExcludeCubebAggregate,
IncludeCubebAggregate,
}
pub fn test_get_all_devices(filter: DeviceFilter) -> Vec<AudioObjectID> {
let mut devices = Vec::new();
let address = AudioObjectPropertyAddress {
mSelector: kAudioHardwarePropertyDevices,
@ -284,11 +288,26 @@ pub fn test_get_all_devices() -> Vec<AudioObjectID> {
for device in devices.iter() {
assert_ne!(*device, kAudioObjectUnknown);
}
match filter {
DeviceFilter::ExcludeCubebAggregate => {
devices.retain(|&device| {
if let Ok(uid) = get_device_global_uid(device) {
let uid = uid.into_string();
!uid.contains(PRIVATE_AGGREGATE_DEVICE_NAME)
} else {
true
}
});
}
_ => {}
}
devices
}
pub fn test_get_devices_in_scope(scope: Scope) -> Vec<AudioObjectID> {
let mut devices = test_get_all_devices();
let mut devices = test_get_all_devices(DeviceFilter::ExcludeCubebAggregate);
devices.retain(|device| test_device_in_scope(*device, scope.clone()));
devices
}