use crate::TestOutcome;
pub use heapless::Vec;
#[cfg_attr(feature = "std", path = "std.rs")]
#[cfg_attr(not(feature = "std"), path = "semihosting.rs")]
mod hosting;
pub fn ensure_linker_file_was_added_to_rustflags() -> ! {
extern "C" {
fn embedded_test_linker_file_not_added_to_rustflags() -> !;
}
unsafe { embedded_test_linker_file_not_added_to_rustflags() }
}
#[cfg(all(feature = "embassy", not(feature = "ariel-os")))]
pub use embassy_executor::task;
#[cfg(all(
feature = "embassy",
not(feature = "external-executor"),
not(feature = "ariel-os")
))]
pub use embassy_executor::Executor;
const VERSION: u32 = 1;
pub const JSON_SIZE_HEADER: usize = r#"{"version:12,tests:[]}"#.len();
pub const JSON_SIZE_PER_TEST_WITHOUT_TESTNAME: usize =
r#"{"name":"","should_panic":false,ignored:false,timeout:1234567890},"#.len();
#[derive(Debug, serde::Serialize)]
pub struct Tests<'a> {
pub version: u32,
pub tests: &'a [Test],
}
#[derive(Debug, serde::Serialize)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct Test {
pub name: &'static str,
#[serde(skip)]
pub function: fn() -> !,
pub should_panic: bool,
pub ignored: bool,
pub timeout: Option<u32>,
}
pub fn run_tests<const JSON_SIZE_TOTAL: usize>(tests: &mut [Test]) -> ! {
for test in tests.iter_mut() {
test.name = &test.name[test.name.find("::").unwrap() + 2..];
}
let args = &hosting::args().expect("Failed to get cmdline via semihosting");
let mut args = args.into_iter();
let command = match args.next() {
Some(c) => c.expect("command to run contains non-utf8 characters"),
None => {
error!("Received no arguments via semihosting. Please communicate with the target with the embedded-test runner.");
hosting::abort();
}
};
match command {
"list" => {
info!("tests available: {:?}", tests);
let tests = Tests {
version: VERSION,
tests,
};
hosting::print_test_list::<JSON_SIZE_TOTAL>(&tests);
hosting::exit(0);
}
"run" => {
let test_name = args.next().expect("test name missing");
let test_name = test_name.expect("test name contains non-utf8 character");
let test = tests
.iter_mut()
.find(|t| t.name == test_name)
.expect("test to run not found");
info!("Running test: {:?}", test);
(test.function)();
}
_ => {
error!("Unknown command: {}", command);
hosting::abort();
}
}
}
pub fn check_outcome<T: TestOutcome>(outcome: T) -> ! {
if outcome.is_success() {
info!("Test exited with () or Ok(..)");
hosting::exit(0);
} else {
info!("Test exited with Err(..): {:?}", outcome);
hosting::abort();
}
}