aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.run/src/bin/test-examples.rs44
-rw-r--r--docs/dev/pages/abouts/ci.md7
2 files changed, 33 insertions, 18 deletions
diff --git a/.run/src/bin/test-examples.rs b/.run/src/bin/test-examples.rs
index 55976ef..617a745 100644
--- a/.run/src/bin/test-examples.rs
+++ b/.run/src/bin/test-examples.rs
@@ -3,7 +3,7 @@ use std::path::Path;
use colored::Colorize;
use indicatif::ProgressBar;
use serde::Deserialize;
-use tools::{eprintln_cargo_style, println_cargo_style};
+use tools::{eprintln_cargo_style, println_cargo_style, run_parallel};
/// An example's `test.toml` (`[[runs]]` entries).
#[derive(Deserialize)]
@@ -31,7 +31,13 @@ fn main() {
let configs = load_all_test_configs();
- // Count total test cases upfront
+ // Phase 1: build all examples in parallel.
+ if let Err(code) = build_all_examples(&configs) {
+ // `run_parallel` already printed every failed build above.
+ std::process::exit(code);
+ }
+
+ // Phase 2: run the tests serially against the pre-built binaries.
let total: usize = configs.iter().map(|(_, cases)| cases.len()).sum();
let bar = ProgressBar::new(total as u64);
bar.set_style(
@@ -97,18 +103,31 @@ fn load_all_test_configs() -> Vec<(String, Vec<TestCase>)> {
configs
}
-/// Run all example test groups, return number passed
+/// Phase 1: build every example that has a `test.toml` in parallel.
+///
+/// Build tasks are spawned in parallel (like `ci.rs`'s `build_all`); on any
+/// build failure the whole run aborts with the first failure's exit code.
+fn build_all_examples(configs: &[(String, Vec<TestCase>)]) -> Result<(), i32> {
+ let tasks: Vec<(String, String, String)> = configs
+ .iter()
+ .map(|(name, _)| {
+ (
+ format!("Build: {name}"),
+ name.clone(),
+ format!("cargo build --manifest-path examples/{name}/Cargo.toml --color always"),
+ )
+ })
+ .collect();
+ run_parallel("Building", tasks)
+}
+
+/// Phase 2: run all example test groups serially, return number passed
fn run_all_tests(configs: &[(String, Vec<TestCase>)], bar: &ProgressBar) -> usize {
let mut passed = 0;
for (example_name, test_cases) in configs {
bar.set_message(example_name.clone());
- if !build_example(example_name) {
- bar.inc(test_cases.len() as u64);
- continue;
- }
-
for test_case in test_cases {
if run_single_test(example_name, test_case, bar) {
passed += 1;
@@ -120,15 +139,6 @@ fn run_all_tests(configs: &[(String, Vec<TestCase>)], bar: &ProgressBar) -> usiz
passed
}
-/// Build the example binary, return true on success
-fn build_example(example_name: &str) -> bool {
- let manifest = format!("examples/{example_name}/Cargo.toml");
- tools::run_cmd_capture(format!(
- "cargo build --manifest-path {manifest} --color always",
- ))
- .is_ok()
-}
-
/// Run a single test case, return true on pass
fn run_single_test(example_name: &str, test_case: &TestCase, bar: &ProgressBar) -> bool {
let binary_path = format!(".temp/target/debug/{}", get_binary_name(example_name));
diff --git a/docs/dev/pages/abouts/ci.md b/docs/dev/pages/abouts/ci.md
index 659a5fc..9f638d7 100644
--- a/docs/dev/pages/abouts/ci.md
+++ b/docs/dev/pages/abouts/ci.md
@@ -51,7 +51,12 @@ Finally, it runs `cargo fmt` to unify code formatting. Because the refresh tools
### Examples in detail
-`--check-examples` runs the `test-examples` tool, which scans `examples/*/test.toml`. Each file contains `[[runs]]` entries declaring the CLI arguments (`input`) and the expected `exit-code` / `result`. The tool builds every example that has a `test.toml` and executes each run against the built binary, so an example that changes its behavior only needs its own `test.toml` updated.
+`--check-examples` runs the `test-examples` tool in two phases:
+
+1. **Build** — every example that has a `test.toml` is built in parallel (one `cargo build` task per example, reusing the shared `.temp/target` cache).
+2. **Test** — each `[[runs]]` entry in `examples/*/test.toml` is executed serially against the pre-built binary, asserting the CLI arguments (`input`) and the expected `exit-code` / `result`.
+
+An example that changes its behavior only needs its own `test.toml` updated.
### Combining steps