Skip to content

Commit 0efd040

Browse files
bors[bot]japaric
andauthored
Merge #604
604: defmt-test: `#[cfg(test)]` the `#[defmt_test::tests]` module r=Urhengulas a=japaric [it recently came to my attention](knurling-rs/app-template@1ebc0ac) that one can use `defmt-test` for "unit testing" by using it in `src/lib.rs` (although this is pretty limited at the moment because one can only use the `defmt_test::tests` *once* in a library crate) if one does use `defmt_test` like that then they may run into the issue that running the test files in `tests` fails with this cryptic linker message: ``` console = note: rust-lld: error: duplicate symbol: main ``` the issue is that the code generated by `defmt_test::tests` (which includes a function with unmangled name `main`) is not conditionally compiled but we do want that to be `#[cfg(test)]`-ed because it contains test code. r? `@jonas-schievink` Co-authored-by: Jorge Aparicio <jorge.aparicio@ferrous-systems.com>
2 parents 2ca740b + 7863152 commit 0efd040

9 files changed

Lines changed: 46 additions & 15 deletions

File tree

firmware/defmt-test/macros/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,9 @@ fn tests_impl(args: TokenStream, input: TokenStream) -> parse::Result<TokenStrea
214214
}
215215
})
216216
.collect::<Vec<_>>();
217-
Ok(quote!(mod #ident {
217+
Ok(quote!(
218+
#[cfg(test)]
219+
mod #ident {
218220
#(#untouched_tokens)*
219221
// TODO use `cortex-m-rt::entry` here to get the `static mut` transform
220222
#[export_name = "main"]

firmware/qemu/.cargo/config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[alias]
2+
tt = "-q test --target thumbv7m-none-eabi --test"
23
rb = "-q run --target thumbv7m-none-eabi --bin"
34
rrb = "-q run --target thumbv7m-none-eabi --release --bin"
45

firmware/qemu/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ name = "firmware"
66
publish = false
77
version = "0.1.0"
88

9+
[[test]]
10+
name = "defmt-test"
11+
harness = false
12+
913
[dependencies]
1014
defmt = { path = "../../defmt" }
1115
defmt-semihosting = { path = "../defmt-semihosting" }

firmware/qemu/tests/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.new

xtask/src/backcompat.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,12 @@ impl QemuRun {
9898
fn run_snapshot(&self, name: &str) -> anyhow::Result<()> {
9999
println!("{}", name.bold());
100100

101+
let is_test = name.contains("test");
102+
let command = if is_test { "tt" } else { "rb" };
103+
101104
run_silently(
102105
Command::new("cargo")
103-
.args(["-q", "rb", name])
106+
.args(["-q", command, name])
104107
.current_dir(SNAPSHOT_TESTS_DIRECTORY)
105108
.env(RUNNER_ENV_VAR, self.path()),
106109
|| anyhow!("{}", name.to_string()),

xtask/src/main.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,13 @@ fn test_all_snapshots(overwrite: bool) {
331331
fn test_single_snapshot(name: &str, features: &str, overwrite: bool) -> anyhow::Result<()> {
332332
println!("{}", name.bold());
333333

334-
let mut args = vec!["-q", "rb", name];
334+
let is_test = name.contains("test");
335+
336+
let mut args = if is_test {
337+
vec!["-q", "tt", name]
338+
} else {
339+
vec!["-q", "rb", name]
340+
};
335341

336342
if !features.is_empty() {
337343
args.extend_from_slice(&["--features", features]);
@@ -346,11 +352,11 @@ fn test_single_snapshot(name: &str, features: &str, overwrite: bool) -> anyhow::
346352
.with_context(|| name.to_string())?;
347353

348354
if overwrite {
349-
overwrite_expected_output(name, actual.as_bytes())?;
355+
overwrite_expected_output(name, actual.as_bytes(), is_test)?;
350356
return Ok(());
351357
}
352358

353-
let expected = load_expected_output(name)?;
359+
let expected = load_expected_output(name, is_test)?;
354360
let diff = TextDiff::from_lines(&expected, &actual);
355361

356362
// if anything isn't ChangeTag::Equal, print it and turn on error flag

xtask/src/utils.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
1-
use std::{fs, path::Path, process::Command, str};
1+
use std::{
2+
fs,
3+
path::{Path, PathBuf},
4+
process::Command,
5+
str,
6+
};
27

38
use anyhow::{anyhow, Context};
49
use colored::Colorize;
510

6-
pub fn load_expected_output(name: &str) -> anyhow::Result<String> {
7-
let file = expected_output_path(name);
8-
let path = Path::new(&file);
11+
pub fn load_expected_output(name: &str, is_test: bool) -> anyhow::Result<String> {
12+
let path = expected_output_path(name, is_test);
913

10-
fs::read_to_string(path).with_context(|| {
14+
fs::read_to_string(&path).with_context(|| {
1115
format!(
1216
"Failed to load expected output data from {}",
1317
path.to_str().unwrap_or("(non-Unicode path)")
1418
)
1519
})
1620
}
1721

18-
pub fn overwrite_expected_output(name: &str, contents: &[u8]) -> anyhow::Result<()> {
19-
let file = expected_output_path(name);
22+
pub fn overwrite_expected_output(name: &str, contents: &[u8], is_test: bool) -> anyhow::Result<()> {
23+
let file = expected_output_path(name, is_test);
2024
let path = Path::new(&file);
2125

2226
fs::write(path, contents).with_context(|| {
@@ -27,9 +31,19 @@ pub fn overwrite_expected_output(name: &str, contents: &[u8]) -> anyhow::Result<
2731
})
2832
}
2933

30-
fn expected_output_path(name: &str) -> String {
31-
const BASE: &str = "firmware/qemu/src/bin";
32-
format!("{}/{}.out", BASE, name)
34+
fn expected_output_path(name: &str, is_test: bool) -> PathBuf {
35+
const PROJECT_DIR: &str = "firmware/qemu";
36+
37+
let mut path = PathBuf::from(PROJECT_DIR);
38+
if is_test {
39+
path.push("tests")
40+
} else {
41+
path.push("src");
42+
path.push("bin");
43+
};
44+
path.push(name);
45+
path.set_extension("out");
46+
path
3347
}
3448

3549
/// Execute the [`Command`]. If success return `stdout`, if failure print to `stderr`

0 commit comments

Comments
 (0)