Skip to content

Commit b829f35

Browse files
committed
add single chip test that can take a url
``` cargo regress test -a cortex-m --url https://raw.githubusercontent.com/cmsis-svd/cmsis-svd/9c416c5ff18e7d272a792c13bd235ebe30eef816/data/ARM_SAMPLE/CMSDK_CM3.svd ```
1 parent 6570752 commit b829f35

File tree

4 files changed

+122
-24
lines changed

4 files changed

+122
-24
lines changed

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,9 @@ features = ["full","extra-traits"]
7474
members = ["ci/svd2rust-regress"]
7575
default-members = ["."]
7676
exclude = [
77-
"output/**",
78-
# workaround for https://github.com/rust-lang/cargo/pull/12779
77+
"output",
78+
# workaround for https://github.com/rust-lang/cargo/pull/12779, doesn't work for output though
79+
# see https://github.com/rust-lang/cargo/issues/6009#issuecomment-1925445245
7980
"output/baseline/**",
8081
"output/current/**"
8182
]

ci/svd2rust-regress/src/main.rs

Lines changed: 112 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ pub fn get_cargo_workspace() -> &'static std::path::Path {
5050
}
5151

5252
#[derive(clap::Parser, Debug)]
53-
pub struct TestOpts {
53+
pub struct TestAll {
5454
/// Run a long test (it's very long)
5555
#[clap(short = 'l', long)]
5656
pub long_test: bool,
@@ -59,7 +59,7 @@ pub struct TestOpts {
5959
#[clap(short = 'c', long)]
6060
pub chip: Vec<String>,
6161

62-
/// Filter by manufacturer, case sensitive, may be combined with other filters
62+
/// Filter by manufacturer, may be combined with other filters
6363
#[clap(
6464
short = 'm',
6565
long = "manufacturer",
@@ -68,7 +68,7 @@ pub struct TestOpts {
6868
)]
6969
pub mfgr: Option<String>,
7070

71-
/// Filter by architecture, case sensitive, may be combined with other filters
71+
/// Filter by architecture, may be combined with other filters
7272
#[clap(
7373
short = 'a',
7474
long = "architecture",
@@ -104,7 +104,97 @@ pub struct TestOpts {
104104
// TODO: Compile svd2rust?
105105
}
106106

107-
impl TestOpts {
107+
#[derive(clap::Parser, Debug)]
108+
// TODO: Replace with https://github.com/clap-rs/clap/issues/2621 when available
109+
#[group(id = "svd_source", required = true)]
110+
pub struct Test {
111+
/// Enable formatting with `rustfmt`
112+
#[arg(short = 'f', long)]
113+
pub format: bool,
114+
115+
#[arg(long)]
116+
/// Enable splitting `lib.rs` with `form`
117+
pub form_lib: bool,
118+
119+
#[arg(
120+
short = 'm',
121+
long = "manufacturer",
122+
ignore_case = true,
123+
value_parser = manufacturers(),
124+
)]
125+
/// Manufacturer
126+
pub mfgr: Option<String>,
127+
#[arg(
128+
short = 'a',
129+
long = "architecture",
130+
ignore_case = true,
131+
value_parser = architectures(),
132+
)]
133+
/// Architecture
134+
pub arch: Option<String>,
135+
#[arg(long, group = "svd_source", conflicts_with_all = ["svd_file"], requires = "arch")]
136+
/// URL to SVD file to test
137+
pub url: Option<String>,
138+
#[arg(long = "svd", group = "svd_source")]
139+
/// Path to SVD file to test
140+
pub svd_file: Option<PathBuf>,
141+
#[arg(long, group = "svd_source")]
142+
/// Chip to use, use `--url` or `--svd-file` for another way to specify svd
143+
pub chip: Option<String>,
144+
145+
/// Path to an `svd2rust` binary, relative or absolute.
146+
/// Defaults to `target/release/svd2rust[.exe]` of this repository
147+
/// (which must be already built)
148+
#[clap(short = 'p', long = "svd2rust-path", default_value = default_svd2rust())]
149+
pub current_bin_path: PathBuf,
150+
#[clap(last = true)]
151+
pub command: Option<String>,
152+
}
153+
154+
impl Test {
155+
fn run(&self, opts: &Opts) -> Result<(), anyhow::Error> {
156+
match self {
157+
Self { url: Some(url), .. } => {}
158+
Self {
159+
svd_file: Some(svd_file),
160+
..
161+
} => {}
162+
Self {
163+
chip: Some(chip), ..
164+
} => {}
165+
_ => unreachable!("clap should not allow this"),
166+
}
167+
let test = if let (Some(url), Some(arch)) = (&self.url, &self.arch) {
168+
tests::TestCase {
169+
arch: svd2rust::Target::parse(&arch)?,
170+
mfgr: tests::Manufacturer::Unknown,
171+
chip: self
172+
.chip
173+
.as_deref()
174+
.or_else(|| url.rsplit('/').next().and_then(|s| s.strip_suffix(".svd")))
175+
.ok_or_else(|| {
176+
anyhow::anyhow!(
177+
"could not figure out chip name, specify with `--chip <name>`",
178+
)
179+
})?
180+
.to_owned(),
181+
svd_url: Some(url.clone()),
182+
should_pass: true,
183+
run_when: tests::RunWhen::default(),
184+
}
185+
} else {
186+
tests::tests(Some(&opts.test_cases))?
187+
.iter()
188+
.find(|t| self.chip.iter().any(|c| WildMatch::new(c).matches(&t.chip)))
189+
.ok_or_else(|| anyhow::anyhow!("no test found for chip"))?
190+
.to_owned()
191+
};
192+
test.test(opts, &self.current_bin_path, self.command.as_deref())?;
193+
Ok(())
194+
}
195+
}
196+
197+
impl TestAll {
108198
fn run(&self, opt: &Opts) -> Result<(), anyhow::Error> {
109199
let tests = tests::tests(Some(&opt.test_cases))?
110200
.iter()
@@ -152,7 +242,7 @@ impl TestOpts {
152242
tests.par_iter().for_each(|t| {
153243
let start = Instant::now();
154244

155-
match t.test(opt, self) {
245+
match t.test(opt, &self.current_bin_path, self.command.as_deref()) {
156246
Ok(s) => {
157247
if let Some(stderrs) = s {
158248
let mut buf = String::new();
@@ -217,7 +307,8 @@ impl TestOpts {
217307
#[derive(clap::Subcommand, Debug)]
218308
pub enum Subcommand {
219309
Diff(Diffing),
220-
Tests(TestOpts),
310+
Tests(TestAll),
311+
Test(Test),
221312
Ci(Ci),
222313
}
223314

@@ -256,15 +347,17 @@ pub struct Opts {
256347
impl Opts {
257348
const fn use_rustfmt(&self) -> bool {
258349
match self.subcommand {
259-
Subcommand::Tests(TestOpts { format, .. })
350+
Subcommand::Tests(TestAll { format, .. })
351+
| Subcommand::Test(Test { format, .. })
260352
| Subcommand::Diff(Diffing { format, .. })
261353
| Subcommand::Ci(Ci { format, .. }) => format,
262354
}
263355
}
264356

265357
const fn use_form(&self) -> bool {
266358
match self.subcommand {
267-
Subcommand::Tests(TestOpts { form_lib, .. })
359+
Subcommand::Tests(TestAll { form_lib, .. })
360+
| Subcommand::Test(Test { form_lib, .. })
268361
| Subcommand::Diff(Diffing {
269362
form_split: form_lib,
270363
..
@@ -278,13 +371,10 @@ impl Opts {
278371
fn default_test_cases() -> std::ffi::OsString {
279372
std::env::var_os("CARGO_MANIFEST_DIR").map_or_else(
280373
|| std::ffi::OsString::from("tests.yml".to_owned()),
281-
|mut e| {
282-
e.extend([std::ffi::OsStr::new("/tests.yml")]);
283-
std::path::PathBuf::from(e)
284-
.strip_prefix(std::env::current_dir().unwrap())
285-
.unwrap()
286-
.to_owned()
287-
.into_os_string()
374+
|path| {
375+
let path = std::path::PathBuf::from(path);
376+
let path = path.join("tests.yml");
377+
path.to_owned().into_os_string()
288378
},
289379
)
290380
}
@@ -414,6 +504,13 @@ fn main() -> Result<(), anyhow::Error> {
414504
}
415505
Subcommand::Diff(diff) => diff.run(&opt).with_context(|| "failed to run diff"),
416506
Subcommand::Ci(ci) => ci.run(&opt).with_context(|| "failed to run ci"),
507+
Subcommand::Test(test) => {
508+
anyhow::ensure!(
509+
test.current_bin_path.exists(),
510+
"svd2rust binary does not exist"
511+
);
512+
test.run(&opt).with_context(|| "failed to run test")
513+
}
417514
}
418515
}
419516

ci/svd2rust-regress/src/svd_test.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::{anyhow, Context, Result};
22
use svd2rust::{util::ToSanitizedCase, Target};
33

4-
use crate::{command::CommandExt, tests::TestCase, Opts, TestOpts};
4+
use crate::{command::CommandExt, tests::TestCase, Opts, TestAll};
55
use std::io::prelude::*;
66
use std::path::PathBuf;
77
use std::process::Command;
@@ -133,17 +133,18 @@ impl CommandHelper for Command {
133133
}
134134

135135
impl TestCase {
136-
#[tracing::instrument(skip(self, opts, test_opts), fields(name = %self.name()))]
136+
#[tracing::instrument(skip(self, opts), fields(name = %self.name()))]
137137
pub fn test(
138138
&self,
139139
opts: &Opts,
140-
test_opts: &TestOpts,
140+
bin_path: &Path,
141+
command: Option<&str>,
141142
) -> Result<Option<Vec<PathBuf>>, TestError> {
142143
let (chip_dir, mut process_stderr_paths) = self
143144
.setup_case(
144145
&opts.output_dir,
145-
&test_opts.current_bin_path,
146-
test_opts.command.as_deref(),
146+
bin_path,
147+
command,
147148
)
148149
.with_context(|| anyhow!("when setting up case for {}", self.name()))?;
149150
// Run `cargo check`, capturing stderr to a log file
@@ -355,7 +356,6 @@ impl TestCase {
355356

356357
process_stderr_paths.push(rustfmt_err_file);
357358
}
358-
tracing::info!("Done processing");
359359
Ok((chip_dir, process_stderr_paths))
360360
}
361361
}

ci/svd2rust-regress/src/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ pub enum RunWhen {
6666
Never,
6767
}
6868

69-
#[derive(serde::Serialize, serde::Deserialize, Clone)]
69+
#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)]
7070
pub struct TestCase {
7171
pub arch: Target,
7272
pub mfgr: Manufacturer,

0 commit comments

Comments
 (0)