Allow running specific tests (#4009)

This commit is contained in:
Dániel Buga 2025-08-29 12:20:43 +02:00 committed by GitHub
parent 9fe02b819c
commit 44b6c3daf1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 48 additions and 13 deletions

View File

@ -147,7 +147,8 @@ pub fn build_examples(
let example_idx = inquire::Select::new(
"Select the example:",
examples.iter().map(|ex| ex.binary_name()).collect(),
).prompt()?;
)
.prompt()?;
if let Some(selected) = examples.iter().find(|ex| ex.binary_name() == example_idx) {
filtered.push(selected);
@ -165,6 +166,7 @@ pub fn build_examples(
args.debug,
args.toolchain.as_deref(),
args.timings,
&[],
)?;
}
@ -182,6 +184,7 @@ pub fn build_examples(
args.debug,
args.toolchain.as_deref(),
args.timings,
&[],
)
})
}

View File

@ -3,11 +3,11 @@ use std::path::Path;
use anyhow::{Result, bail};
use clap::Args;
use esp_metadata::Chip;
use inquire::Select;
use strum::IntoEnumIterator;
pub use self::{build::*, check_changelog::*, release::*, run::*};
use crate::{Package, cargo::CargoAction};
use inquire::Select;
use strum::IntoEnumIterator;
mod build;
mod check_changelog;
mod release;
@ -58,7 +58,9 @@ pub struct TestsArgs {
/// Repeat the tests for a specific number of times.
#[arg(long, default_value_t = 1)]
pub repeat: usize,
/// Optional test to act on (all tests used if omitted)
/// Optional test to act on (all tests used if omitted).
///
/// The `test_suite::test_name` syntax allows running a single specific test.
#[arg(long, short = 't')]
pub test: Option<String>,
@ -129,12 +131,26 @@ pub fn examples(workspace: &Path, mut args: ExamplesArgs, action: CargoAction) -
// Execute the specified action:
match action {
CargoAction::Build(out_path) => build_examples(args, examples, &package_path, out_path.as_ref().map(|p| p.as_path())),
CargoAction::Build(out_path) => build_examples(
args,
examples,
&package_path,
out_path.as_ref().map(|p| p.as_path()),
),
CargoAction::Run => run_examples(args, examples, &package_path),
}
}
pub fn tests(workspace: &Path, args: TestsArgs, action: CargoAction) -> Result<()> {
let (test_arg, filter) = if let Some(test_arg) = args.test.as_deref() {
match test_arg.split_once("::") {
Some((test, filter)) => (Some(test), Some(filter)),
None => (Some(test_arg), None),
}
} else {
(None, None)
};
// Absolute path of the 'hil-test' package's root:
let package_path = crate::windows_safe_path(&workspace.join("hil-test"));
@ -150,9 +166,17 @@ pub fn tests(workspace: &Path, args: TestsArgs, action: CargoAction) -> Result<(
// Sort all tests by name:
tests.sort_by_key(|a| a.binary_name());
let run_test_extra_args = (action == CargoAction::Run)
.then(|| filter.as_ref().map(|f| std::slice::from_ref(f)))
.flatten()
.unwrap_or(&[]);
// Execute the specified action:
if tests.iter().any(|test| test.matches(&args.test)) {
for test in tests.iter().filter(|test| test.matches(&args.test)) {
if tests.iter().any(|test| test.matches(test_arg.as_deref())) {
for test in tests
.iter()
.filter(|test| test.matches(test_arg.as_deref()))
{
crate::execute_app(
&package_path,
args.chip,
@ -163,10 +187,11 @@ pub fn tests(workspace: &Path, args: TestsArgs, action: CargoAction) -> Result<(
false,
args.toolchain.as_deref(),
args.timings,
run_test_extra_args,
)?;
}
Ok(())
} else if args.test.is_some() {
} else if test_arg.is_some() {
bail!("Test not found or unsupported for the given chip")
} else {
let mut failed = Vec::new();
@ -181,6 +206,7 @@ pub fn tests(workspace: &Path, args: TestsArgs, action: CargoAction) -> Result<(
false,
args.toolchain.as_deref(),
args.timings,
run_test_extra_args,
)
.is_err()
{

View File

@ -8,7 +8,7 @@ use anyhow::{Context as _, Result, bail};
use clap::{Args, Subcommand};
use esp_metadata::Chip;
use super::{ExamplesArgs, TestsArgs, DocTestArgs};
use super::{DocTestArgs, ExamplesArgs, TestsArgs};
use crate::{
cargo::{CargoAction, CargoArgsBuilder},
firmware::Metadata,
@ -162,7 +162,10 @@ pub fn run_examples(
)
.prompt()?;
if let Some(selected) = examples.into_iter().find(|ex| ex.binary_name() == example_idx) {
if let Some(selected) = examples
.into_iter()
.find(|ex| ex.binary_name() == example_idx)
{
filtered.push(selected);
}
}
@ -170,7 +173,6 @@ pub fn run_examples(
examples = filtered;
}
examples.sort_by_key(|ex| ex.tag());
let console = console::Term::stdout();
@ -213,6 +215,7 @@ pub fn run_examples(
args.debug,
args.toolchain.as_deref(),
args.timings,
&[],
)
.is_err()
{

View File

@ -93,8 +93,8 @@ impl Metadata {
self.description.clone()
}
pub fn matches(&self, filter: &Option<String>) -> bool {
let Some(filter) = filter.as_deref() else {
pub fn matches(&self, filter: Option<&str>) -> bool {
let Some(filter) = filter else {
return false;
};

View File

@ -371,6 +371,7 @@ pub fn execute_app(
debug: bool,
toolchain: Option<&str>,
timings: bool,
extra_args: &[&str],
) -> Result<()> {
let package = app.example_path().strip_prefix(package_path)?;
log::info!("Building example '{}' for '{}'", package.display(), chip);
@ -447,6 +448,8 @@ pub fn execute_app(
builder = builder.toolchain(toolchain);
}
builder = builder.args(extra_args);
let args = builder.build();
log::debug!("{args:#?}");