This repository has been archived on 2026-08-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
donglora/vendor/usb-device/tests/test_class_host/main.rs
T
swaitsandClaude Opus 4.6 3102fc747a feat: add display UI with splash screen, dashboard, and RSSI sparkline
Implement full SSD1306 OLED display support:
- Splash screen on boot (1.5s) with project name, version, board
- Dashboard showing radio state, config, counters, RSSI/SNR
- RSSI history sparkline (64-sample ring buffer, 2px-wide bars)
- DisplayOn/DisplayOff host commands routed via dedicated channel
- Pure render functions against generic DrawTarget (no hardware coupling)
- Display on/off control bypasses radio task entirely

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:42:54 -06:00

117 lines
3.3 KiB
Rust

mod device;
/// Runs tests against a TestClass device running on actual hardware using libusb.
///
/// This is implemented as an example as opposed to a test because the Rust test runner system is
/// not well suited for running tests that must depend on outside resources such as hardware and
/// cannot be run in parallel.
mod tests;
use crate::device::open_device;
use crate::tests::{get_tests, TestFn};
use std::io::prelude::*;
use std::io::stdout;
use std::panic;
use std::thread;
use std::time::Duration;
use usb_device::device::CONFIGURATION_VALUE;
fn main() {
let tests = get_tests();
run_tests(&tests[..]);
}
fn run_tests(tests: &[(&str, TestFn)]) {
const INTERFACE: u8 = 0;
println!("test_class_host starting");
println!("looking for device...");
let ctx = rusb::Context::new().expect("create libusb context");
// Look for the device for about 5 seconds in case it hasn't finished enumerating yet
let mut dev = Err(rusb::Error::NoDevice);
for _ in 0..50 {
dev = open_device(&ctx);
if dev.is_ok() {
break;
}
thread::sleep(Duration::from_millis(100));
}
let mut dev = match dev {
Ok(d) => d,
Err(err) => {
println!("Did not find a TestClass device. Make sure the device is correctly programmed and plugged in. Last error: {}", err);
return;
}
};
println!("\nrunning {} tests", tests.len());
let mut success = 0;
for (name, test) in tests {
if let Err(err) = dev.reset() {
println!("Failed to reset the device: {}", err);
return;
}
if let Err(err) = dev.set_active_configuration(CONFIGURATION_VALUE) {
println!("Failed to set active configuration: {}", err);
return;
}
if let Err(err) = dev.claim_interface(INTERFACE) {
println!("Failed to claim interface: {}", err);
return;
}
print!("test {} ... ", name);
let _ = stdout().flush();
let mut out = String::new();
let res = {
let hook = panic::take_hook();
panic::set_hook(Box::new(|_| {}));
let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
test(&mut dev, &mut out);
}));
panic::set_hook(hook);
res
};
dev.release_interface(INTERFACE)
.expect("failed to release interface");
if let Err(err) = res {
let err = if let Some(err) = err.downcast_ref::<&'static str>() {
String::from(*err)
} else if let Some(err) = err.downcast_ref::<String>() {
err.clone()
} else {
String::from("???")
};
println!("FAILED\nerror: {}\n", err);
} else {
println!("ok");
if !out.is_empty() {
print!("{}", out);
}
success += 1;
}
}
println!("{} failed, {} succeeded", tests.len() - success, success);
if success == tests.len() {
println!("\nALL TESTS PASSED!");
} else {
std::process::exit(1);
}
}