aboutsummaryrefslogtreecommitdiff
path: root/xtask
diff options
context:
space:
mode:
Diffstat (limited to 'xtask')
-rw-r--r--xtask/Cargo.toml1
-rw-r--r--xtask/src/build.rs10
-rw-r--r--xtask/src/command.rs33
-rw-r--r--xtask/src/main.rs327
4 files changed, 133 insertions, 238 deletions
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml
index fa7fd179..33e6b3ad 100644
--- a/xtask/Cargo.toml
+++ b/xtask/Cargo.toml
@@ -7,4 +7,3 @@ edition = "2018"
anyhow = "1.0.43"
os_pipe = "0.9.2"
structopt = "0.3.22"
-tempdir = "0.3.7" \ No newline at end of file
diff --git a/xtask/src/build.rs b/xtask/src/build.rs
index a8c19aac..904e9177 100644
--- a/xtask/src/build.rs
+++ b/xtask/src/build.rs
@@ -38,14 +38,14 @@ pub fn build_hexpath(
.map_err(|e| anyhow::Error::new(TestRunError::PathConversionError(e)))
}
-pub fn compare_builds(file_1: String, file_2: String) -> anyhow::Result<()> {
- let buf_1 = std::fs::read_to_string(file_1.clone())?;
- let buf_2 = std::fs::read_to_string(file_2.clone())?;
+pub fn compare_builds(expected: String, got: String) -> anyhow::Result<()> {
+ let buf_1 = std::fs::read_to_string(expected.clone())?;
+ let buf_2 = std::fs::read_to_string(got.clone())?;
if buf_1 != buf_2 {
return Err(anyhow::Error::new(TestRunError::FileCmpError {
- file_1,
- file_2,
+ expected,
+ got,
}));
}
diff --git a/xtask/src/command.rs b/xtask/src/command.rs
index 8bf49849..d94a7ab3 100644
--- a/xtask/src/command.rs
+++ b/xtask/src/command.rs
@@ -1,14 +1,16 @@
-use crate::RunResult;
+use crate::{RunResult, TestRunError};
use core::fmt;
use os_pipe::pipe;
use std::{fs::File, io::Read, path::Path, process::Command};
+#[allow(dead_code)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BuildMode {
Release,
Debug,
}
+#[derive(Debug)]
pub enum CargoCommand<'a> {
Run {
example: &'a str,
@@ -146,17 +148,26 @@ pub fn run_command(command: &CargoCommand) -> anyhow::Result<RunResult> {
/// Check if `run` was sucessful.
/// returns Ok in case the run went as expected,
/// Err otherwise
-pub fn run_successful(run: &RunResult, expected_output_file: String) -> anyhow::Result<()> {
- let mut file_handle = File::open(expected_output_file)?;
+pub fn run_successful(run: &RunResult, expected_output_file: String) -> Result<(), TestRunError> {
+ let mut file_handle =
+ File::open(expected_output_file.clone()).map_err(|_| TestRunError::FileError {
+ file: expected_output_file.clone(),
+ })?;
let mut expected_output = String::new();
- file_handle.read_to_string(&mut expected_output)?;
- if expected_output == run.output && run.exit_status.success() {
- Ok(())
+ file_handle
+ .read_to_string(&mut expected_output)
+ .map_err(|_| TestRunError::FileError {
+ file: expected_output_file.clone(),
+ })?;
+
+ if expected_output != run.output {
+ Err(TestRunError::FileCmpError {
+ expected: expected_output.clone(),
+ got: run.output.clone(),
+ })
+ } else if !run.exit_status.success() {
+ Err(TestRunError::CommandError(run.clone()))
} else {
- Err(anyhow::anyhow!(
- "Run failed with exit status {}: {}",
- run.exit_status,
- run.output
- ))
+ Ok(())
}
}
diff --git a/xtask/src/main.rs b/xtask/src/main.rs
index 3243b98e..ad8719ad 100644
--- a/xtask/src/main.rs
+++ b/xtask/src/main.rs
@@ -27,15 +27,16 @@ struct Options {
target: String,
}
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub struct RunResult {
exit_status: ExitStatus,
output: String,
}
#[derive(Debug)]
-enum TestRunError {
- FileCmpError { file_1: String, file_2: String },
+pub enum TestRunError {
+ FileCmpError { expected: String, got: String },
+ FileError { file: String },
PathConversionError(OsString),
CommandError(RunResult),
IncompatibleCommand,
@@ -44,8 +45,17 @@ enum TestRunError {
impl fmt::Display for TestRunError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
- TestRunError::FileCmpError { file_1, file_2 } => {
- write!(f, "Differing output in Files: {} {}", file_1, file_2)
+ TestRunError::FileCmpError { expected, got } => {
+ writeln!(f, "Differing output in files.")?;
+ writeln!(f, "")?;
+ writeln!(f, "Expected:")?;
+ writeln!(f, "{}", expected)?;
+ writeln!(f, "")?;
+ writeln!(f, "Got:")?;
+ write!(f, "{}", got)
+ }
+ TestRunError::FileError { file } => {
+ write!(f, "File error on: {}", file)
}
TestRunError::CommandError(e) => {
write!(
@@ -75,25 +85,32 @@ fn main() -> anyhow::Result<()> {
}
let targets = [ARMV7M, ARMV6M];
- let examples = &[
- "idle",
- "init",
- "hardware",
- "preempt",
- "binds",
- "resource",
- "lock",
- "multilock",
- "only-shared-access",
- "task",
- "message",
- "capacity",
- "not-sync",
- "generics",
- "pool",
- "ramfunc",
- "peripherals-taken",
- ];
+
+ let examples: Vec<_> = std::fs::read_dir("./examples")?
+ .filter_map(|path| {
+ path.map(|p| p.path().file_stem().unwrap().to_str().unwrap().to_string())
+ .ok()
+ })
+ .collect();
+
+ // let examples = &[
+ // "idle",
+ // "init",
+ // "hardware",
+ // "preempt",
+ // "binds",
+ // "lock",
+ // "multilock",
+ // "only-shared-access",
+ // "task",
+ // "message",
+ // "capacity",
+ // "not-sync",
+ // "generics",
+ // "pool",
+ // "ramfunc",
+ // "peripherals-taken",
+ // ];
let opts = Options::from_args();
let target = &opts.target;
@@ -102,12 +119,12 @@ fn main() -> anyhow::Result<()> {
if target == "all" {
for t in targets {
- run_test(t, examples)?;
- build_test(t, examples)?;
+ run_test(t, &examples)?;
+ build_test(t, &examples)?;
}
} else if targets.contains(&target.as_str()) {
- run_test(&target, examples)?;
- build_test(&target, examples)?;
+ run_test(&target, &examples)?;
+ build_test(&target, &examples)?;
} else {
eprintln!(
"The target you specified is not available. Available targets are:\
@@ -121,115 +138,26 @@ fn main() -> anyhow::Result<()> {
Ok(())
}
-fn run_test(target: &str, examples: &[&str]) -> anyhow::Result<()> {
+fn run_test(target: &str, examples: &[String]) -> anyhow::Result<()> {
for example in examples {
- match *example {
- "pool" => {
- if target != ARMV6M {
- // check this one manually because addresses printed in `pool.run` may vary
- let features_v7 = Some("__v7");
-
- let debug_run_result = run_command(&CargoCommand::Run {
- example,
- target,
- features: features_v7,
- mode: BuildMode::Debug,
- })?;
-
- if debug_run_result.exit_status.success() {
- print_from_output("foo(0x2", &debug_run_result.output);
- print_from_output("bar(0x2", &debug_run_result.output);
- }
-
- let hexpath = &build_hexpath(*example, features_v7, BuildMode::Debug, 1)?;
-
- run_command(&CargoCommand::Objcopy {
- example,
- target,
- features: features_v7,
- ihex: hexpath,
- })?;
-
- let release_run_result = run_command(&CargoCommand::Run {
- example,
- target,
- features: features_v7,
- mode: BuildMode::Release,
- })?;
-
- if release_run_result.exit_status.success() {
- print_from_output("foo(0x2", &release_run_result.output);
- print_from_output("bar(0x2", &release_run_result.output);
- }
-
- let hexpath = &build_hexpath(*example, features_v7, BuildMode::Release, 1)?;
- run_command(&CargoCommand::Objcopy {
- example,
- target,
- features: features_v7,
- ihex: hexpath,
- })?;
- }
- }
- "types" => {
- let features_v7 = Some("__v7");
-
- // TODO this example doesn't exist anymore, can we remove this case?
- if target != ARMV6M {
- arm_example(
- &CargoCommand::Run {
- example,
- target,
- features: features_v7,
- mode: BuildMode::Debug,
- },
- 1,
- )?;
- arm_example(
- &CargoCommand::Run {
- example,
- target,
- features: features_v7,
- mode: BuildMode::Release,
- },
- 1,
- )?;
- }
- }
- _ => {
- arm_example(
- &CargoCommand::Run {
- example,
- target,
- features: None,
- mode: BuildMode::Debug,
- },
- 1,
- )?;
-
- if *example == "types" {
- arm_example(
- &CargoCommand::Run {
- example,
- target,
- features: None,
- mode: BuildMode::Release,
- },
- 1,
- )?;
- } else {
- arm_example(
- &CargoCommand::Build {
- example,
- target,
- features: None,
- mode: BuildMode::Release,
- },
- 1,
- )?;
- }
- }
- }
+ let cmd = CargoCommand::Run {
+ example,
+ target,
+ features: None,
+ mode: BuildMode::Release,
+ };
+
+ arm_example(&cmd, 1)?;
+
+ arm_example(
+ &CargoCommand::Build {
+ example,
+ target,
+ features: None,
+ mode: BuildMode::Release,
+ },
+ 1,
+ )?;
}
Ok(())
@@ -264,11 +192,7 @@ fn arm_example(command: &CargoCommand, build_num: u32) -> anyhow::Result<()> {
match &command {
CargoCommand::Run { .. } => {
- if run_successful(&cargo_run_result, expected_output_file).is_err() {
- return Err(anyhow::Error::new(TestRunError::CommandError(
- cargo_run_result,
- )));
- }
+ run_successful(&cargo_run_result, expected_output_file)?;
}
_ => (),
}
@@ -289,82 +213,43 @@ fn arm_example(command: &CargoCommand, build_num: u32) -> anyhow::Result<()> {
}
}
-fn build_test(target: &str, examples: &[&str]) -> anyhow::Result<()> {
+fn build_test(target: &str, examples: &[String]) -> anyhow::Result<()> {
run_command(&CargoCommand::Clean)?;
let mut built = vec![];
- let build_path: PathBuf = ["target", target, "debug", "examples"].iter().collect();
+ let build_path: PathBuf = ["target", target, "release", "examples"].iter().collect();
for example in examples {
- match *example {
- "pool" | "types" => {
- if target != ARMV6M {
- let features_v7 = Some("__v7");
-
- arm_example(
- &CargoCommand::Build {
- target,
- example,
- mode: BuildMode::Debug,
- features: features_v7,
- },
- 2,
- )?;
- let file_1 = build_hexpath(example, features_v7, BuildMode::Debug, 1)?;
- let file_2 = build_hexpath(example, features_v7, BuildMode::Debug, 2)?;
-
- compare_builds(file_1, file_2)?;
-
- arm_example(
- &CargoCommand::Build {
- target,
- example,
- mode: BuildMode::Release,
- features: features_v7,
- },
- 2,
- )?;
- let file_1 = build_hexpath(example, features_v7, BuildMode::Release, 1)?;
- let file_2 = build_hexpath(example, features_v7, BuildMode::Release, 2)?;
-
- compare_builds(file_1, file_2)?;
-
- built.push(build_path.join(example));
- }
- }
- _ => {
- let no_features = None;
- arm_example(
- &CargoCommand::Build {
- target,
- example,
- mode: BuildMode::Debug,
- features: no_features,
- },
- 2,
- )?;
- let file_1 = build_hexpath(example, no_features, BuildMode::Debug, 1)?;
- let file_2 = build_hexpath(example, no_features, BuildMode::Debug, 2)?;
-
- compare_builds(file_1, file_2)?;
-
- arm_example(
- &CargoCommand::Build {
- target,
- example,
- mode: BuildMode::Release,
- features: no_features,
- },
- 2,
- )?;
- let file_1 = build_hexpath(example, no_features, BuildMode::Release, 1)?;
- let file_2 = build_hexpath(example, no_features, BuildMode::Release, 2)?;
-
- compare_builds(file_1, file_2)?;
-
- built.push(build_path.join(example));
- }
- }
+ let no_features = None;
+ arm_example(
+ &CargoCommand::Build {
+ target,
+ example,
+ mode: BuildMode::Release,
+ features: no_features,
+ },
+ 2,
+ )?;
+ let expected = build_hexpath(example, no_features, BuildMode::Release, 1)?;
+ let got = build_hexpath(example, no_features, BuildMode::Release, 2)?;
+
+ compare_builds(expected, got)?;
+
+ arm_example(
+ &CargoCommand::Build {
+ target,
+ example,
+ mode: BuildMode::Release,
+ features: no_features,
+ },
+ 2,
+ )?;
+ let expected = build_hexpath(example, no_features, BuildMode::Release, 1)?;
+ let got = build_hexpath(example, no_features, BuildMode::Release, 2)?;
+
+ compare_builds(expected, got)?;
+
+ built.push(build_path.join(example));
}
let example_paths: Vec<&Path> = built.iter().map(|p| p.as_path()).collect();
@@ -377,12 +262,12 @@ fn build_test(target: &str, examples: &[&str]) -> anyhow::Result<()> {
Ok(())
}
-/// Check if lines in `output` contain `pattern` and print matching lines
-fn print_from_output(pattern: &str, lines: &str) {
- let lines = lines.split("\n");
- for line in lines {
- if line.contains(pattern) {
- println!("{}", line);
- }
- }
-}
+// /// Check if lines in `output` contain `pattern` and print matching lines
+// fn print_from_output(pattern: &str, lines: &str) {
+// let lines = lines.split("\n");
+// for line in lines {
+// if line.contains(pattern) {
+// println!("{}", line);
+// }
+// }
+// }