diff --git a/.cargo/config.toml b/.cargo/config.toml index 624c0e4118..4408727172 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,6 +1,6 @@ [alias] compiletest = "run --release -p compiletests --" -difftest = "run --release -p difftests --" +difftest = "nextest run --release -P difftests -p difftests" [target.x86_64-pc-windows-msvc] diff --git a/.config/nextest.toml b/.config/nextest.toml new file mode 100644 index 0000000000..4edcc1c7f3 --- /dev/null +++ b/.config/nextest.toml @@ -0,0 +1,10 @@ +[profile.default] +default-filter = '!package(difftest*) & !package(compiletest*) & !package(example-runner-*)' +fail-fast = false + +[profile.difftests] +default-filter = 'package(difftests)' +slow-timeout = "2m" + +[profile.difftest-runner] +default-filter = 'package(difftest-runner) | package(difftest-types)' diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index fe9b61a9e4..dc1caa0fb2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -16,6 +16,7 @@ jobs: test: name: Test strategy: + fail-fast: false matrix: os: [ ubuntu-24.04, windows-2022, macOS-latest ] runs-on: ${{ matrix.os }} @@ -41,6 +42,8 @@ jobs: # figure out native target triple while we're at it - name: install rust-toolchain run: echo "TARGET=$(rustc --print host-tuple)" >> "$GITHUB_ENV" + - name: install nextest + uses: taiki-e/install-action@nextest # Fetch dependencies in a separate step to clearly show how long each part # of the testing takes - name: cargo fetch --locked @@ -49,13 +52,13 @@ jobs: # Core crates # Compiled in --release because cargo compiletest would otherwise compile in release again. - name: rustc_codegen_spirv build - run: cargo test -p rustc_codegen_spirv --release --no-default-features --features "use-installed-tools" --no-run + run: cargo nextest run -p rustc_codegen_spirv --release --no-default-features --features "use-installed-tools" --no-run - name: rustc_codegen_spirv test - run: cargo test -p rustc_codegen_spirv --release --no-default-features --features "use-installed-tools" + run: cargo nextest run -p rustc_codegen_spirv --release --no-default-features --features "use-installed-tools" - name: workspace test (excluding examples & difftest) - run: cargo test --release --workspace --exclude "example-runner-*" --exclude "difftest*" --no-default-features --features "use-installed-tools" + run: cargo nextest run --release --workspace --exclude "example-runner-*" --exclude "difftest*" --no-default-features --features "use-installed-tools" # Examples - name: cargo check examples @@ -129,6 +132,7 @@ jobs: compiletest: name: Compiletest strategy: + fail-fast: false matrix: os: [ ubuntu-24.04, windows-2022, macOS-latest ] runs-on: ${{ matrix.os }} @@ -154,6 +158,7 @@ jobs: difftest: name: Difftest strategy: + fail-fast: false matrix: os: [ ubuntu-24.04, windows-2022, macOS-latest ] runs-on: ${{ matrix.os }} @@ -181,14 +186,18 @@ jobs: sudo apt install -y xvfb libgl1-mesa-dri libxcb-xfixes0-dev mesa-vulkan-drivers - name: install rust-toolchain run: echo "TARGET=$(rustc --print host-tuple)" >> "$GITHUB_ENV" + - name: install nextest + uses: taiki-e/install-action@nextest - name: cargo fetch --locked run: cargo fetch --locked --target $TARGET - name: cargo fetch --locked difftests run: cargo fetch --locked --manifest-path=tests/difftests/tests/Cargo.toml --target $TARGET - - name: test difftest - run: cargo test -p "difftest*" --release --no-default-features --features "use-installed-tools" + - name: test difftest-runner + run: cargo nextest run -P difftest-runner -p difftest-runner -p difftest-types --release --no-default-features --features "use-installed-tools" + - name: build difftests (without shaders) + run: cargo build --manifest-path ./tests/difftests/tests/Cargo.toml --workspace --release --no-default-features --features "use-installed-tools" - name: difftests - run: cargo run -p difftests --release --no-default-features --features "use-installed-tools" + run: cargo nextest run -P difftests -p difftests --release --no-default-features --features "use-installed-tools" # This allows us to have a single job we can branch protect on, rather than needing # to update the branch protection rules when the test matrix changes diff --git a/Cargo.lock b/Cargo.lock index b03b79cf58..e2f8592814 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -711,38 +711,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] -name = "difftest" +name = "difftest-runner" version = "0.9.0" dependencies = [ "anyhow", - "ash", "bytemuck", - "futures", - "naga", + "bytesize", + "difftest-types", + "libtest-mimic", "serde", "serde_json", - "spirv-builder", + "tabled", "tempfile", - "wgpu", + "thiserror 1.0.69", + "toml", + "tracing", + "tracing-subscriber", ] [[package]] -name = "difftests" +name = "difftest-types" version = "0.9.0" dependencies = [ "anyhow", "bytemuck", - "bytesize", - "difftest", "serde", "serde_json", - "tabled", - "tempfile", - "tester", - "thiserror 1.0.69", - "toml", - "tracing", - "tracing-subscriber", +] + +[[package]] +name = "difftests" +version = "0.9.0" +dependencies = [ + "anyhow", + "difftest-runner", ] [[package]] @@ -857,6 +859,12 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "escape8259" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5692dd7b5a1978a5aeb0ce83b7655c58ca8efdcb79d21036ea249da95afec2c6" + [[package]] name = "example-runner-ash" version = "0.0.0" @@ -1469,6 +1477,18 @@ dependencies = [ "redox_syscall 0.5.8", ] +[[package]] +name = "libtest-mimic" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5297962ef19edda4ce33aaa484386e0a5b3d7f2f4e037cbeee00503ef6b29d33" +dependencies = [ + "anstream", + "anstyle", + "clap", + "escape8259", +] + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -1503,12 +1523,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" -[[package]] -name = "mach-dxcompiler-rs" -version = "0.1.4+2024.11.22-df583a3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e3cd67e8ea2ba061339150970542cf1c60ba44c6d17e31279cbc133a4b018f8" - [[package]] name = "malloc_buf" version = "0.0.6" @@ -1656,7 +1670,6 @@ dependencies = [ "num-traits", "once_cell", "petgraph", - "pp-rs", "rustc-hash", "spirv", "strum", @@ -2215,15 +2228,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "pp-rs" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb458bb7f6e250e6eb79d5026badc10a3ebb8f9a15d1fff0f13d17c71f4d6dee" -dependencies = [ - "unicode-xid", -] - [[package]] name = "presser" version = "0.3.1" @@ -3271,12 +3275,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "utf8parse" version = "0.2.2" @@ -3709,7 +3707,6 @@ dependencies = [ "libc", "libloading", "log", - "mach-dxcompiler-rs", "metal", "naga", "ndk-sys 0.5.0+25.2.9519653", diff --git a/Cargo.toml b/Cargo.toml index 2c852a359d..a17a8c126a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,7 +28,8 @@ members = [ "tests/compiletests", "tests/compiletests/deps-helper", "tests/difftests/bin", - "tests/difftests/lib", + "tests/difftests/runner", + "tests/difftests/types", ] [workspace.package] @@ -50,14 +51,20 @@ spirv-tools = { version = "0.12.1", default-features = false } rustc_codegen_spirv = { path = "./crates/rustc_codegen_spirv", version = "=0.9.0", default-features = false } rustc_codegen_spirv-types = { path = "./crates/rustc_codegen_spirv-types", version = "=0.9.0" } rustc_codegen_spirv-target-specs = { path = "crates/rustc_codegen_spirv-target-specs", version = "=0.9.0" } -tracing = "0.1" -tracing-subscriber = { version = "0.3.3", features = ["env-filter", "json"] } + +# difftest libraries mirrored from difftest workspace +difftest = { path = "tests/difftests/tests/lib" } +difftest-runner = { path = "tests/difftests/runner", default-features = false } +difftest-types = { path = "tests/difftests/types" } # External dependencies that need to be mentioned more than once. +tracing = "0.1" +tracing-subscriber = { version = "0.3.3", features = ["env-filter", "json"] } num-traits = { version = "0.2.15", default-features = false } glam = { version = ">=0.22, <=0.30", default-features = false } # libm 0.2.12 is a breaking change with new intrinsics libm = { version = ">=0.2.5, <=0.2.11", default-features = false } +bytemuck = { version = "1.23", features = ["derive"] } # Enable incremental by default in release mode. [profile.release] diff --git a/crates/rustc_codegen_spirv/Cargo.toml b/crates/rustc_codegen_spirv/Cargo.toml index 5af8dbea20..19fc33e96f 100644 --- a/crates/rustc_codegen_spirv/Cargo.toml +++ b/crates/rustc_codegen_spirv/Cargo.toml @@ -34,7 +34,7 @@ skip-toolchain-check = [] # HACK(eddyb) these only exist to unify features across dependency trees, # in order to avoid multiple separate instances of `rustc_codegen_spirv`. ahash = { version = "0.8.11", features = ["no-rng"] } -bytemuck = { version = "1.20.0", features = ["aarch64_simd", "derive"] } +bytemuck = { workspace = true, features = ["aarch64_simd"] } log = { version = "0.4.22", features = ["std"] } regex = { version = "1", features = ["perf"] } rustix = { version = "0.38.42", features = ["all-apis"] } diff --git a/crates/spirv-std/Cargo.toml b/crates/spirv-std/Cargo.toml index d419f66c14..aaa0f3581f 100644 --- a/crates/spirv-std/Cargo.toml +++ b/crates/spirv-std/Cargo.toml @@ -14,7 +14,7 @@ workspace = true spirv-std-types.workspace = true spirv-std-macros.workspace = true bitflags = "1.2.1" -bytemuck = { version = "1.18.0", features = ["derive"], optional = true } +bytemuck = { workspace = true, optional = true } [target.'cfg(target_arch = "spirv")'.dependencies] num-traits = { workspace = true, features = ["libm"] } diff --git a/tests/difftests/bin/Cargo.toml b/tests/difftests/bin/Cargo.toml index a46a09e561..b40435fc1f 100644 --- a/tests/difftests/bin/Cargo.toml +++ b/tests/difftests/bin/Cargo.toml @@ -9,23 +9,17 @@ repository.workspace = true # See rustc_codegen_spirv/Cargo.toml for details on these features [features] default = ["use-compiled-tools"] -use-installed-tools = [] -use-compiled-tools = [] +use-installed-tools = ["difftest-runner/use-installed-tools"] +use-compiled-tools = ["difftest-runner/use-compiled-tools"] [dependencies] anyhow = "1.0" -tracing = "0.1" -tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] } -tempfile = "3.5" -tester = "0.9.1" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" -thiserror = "1.0" -toml = { version = "0.8.20", default-features = false, features = ["parse"] } -bytesize = "2.0.1" -bytemuck = "1.21.0" -difftest = { path = "../lib" } -tabled = { version = "0.15", default-features = false, features = ["std"] } +difftest-runner.workspace = true [lints] workspace = true + +[[test]] +name = "difftests" +path = "src/test.rs" +harness = false diff --git a/tests/difftests/bin/src/main.rs b/tests/difftests/bin/src/main.rs deleted file mode 100644 index 58614d5a8b..0000000000 --- a/tests/difftests/bin/src/main.rs +++ /dev/null @@ -1,140 +0,0 @@ -#![allow(clippy::exit)] - -use anyhow::Result; -use std::{ - env, - process::{self, Command}, -}; -use tester::{ - ColorConfig, DynTestName, OutputFormat, RunIgnored, ShouldPanic, TestDesc, TestDescAndFn, - TestFn, TestType, run_tests_console, - test::{TestOpts, parse_opts}, -}; -use tracing_subscriber::FmtSubscriber; - -mod differ; -mod runner; -use runner::Runner; - -fn main() -> Result<()> { - let subscriber = FmtSubscriber::builder() - .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) - .finish(); - tracing::subscriber::set_global_default(subscriber).expect("Failed to set global subscriber"); - - let args: Vec = env::args().collect(); - let opts: TestOpts = match parse_opts(&args) { - Some(Ok(o)) => TestOpts { - test_threads: Some(1), - ..o - }, - Some(Err(e)) => { - eprintln!("Error parsing test options: {e}"); - process::exit(1); - } - None => TestOpts { - list: false, - filters: vec![], - filter_exact: false, - force_run_in_process: false, - exclude_should_panic: false, - run_ignored: RunIgnored::No, - run_tests: true, - bench_benchmarks: false, - logfile: None, - nocapture: false, - color: ColorConfig::AutoColor, - format: OutputFormat::Pretty, - test_threads: Some(1), - skip: vec![], - time_options: None, - options: tester::Options { - display_output: true, - panic_abort: true, - }, - }, - }; - - // Find the manifest directory at compile time and locate tests in ../tests. - let manifest_dir = env!("CARGO_MANIFEST_DIR"); - let base = std::path::Path::new(manifest_dir) - .join("../tests") - .canonicalize() - .expect("Failed to canonicalize tests directory"); - tracing::debug!("Using tests directory: {}", base.display()); - - let runner = Runner::new(base.clone()); - - let test_cases = - Runner::collect_test_dirs(&base).expect("Failed to collect test case directories"); - if test_cases.is_empty() { - eprintln!("No valid tests found in {}", base.display()); - process::exit(1); - } - - // We build first to ensure that the tests are compiled before running them and to - // passthrough stdout and stderr from cargo to help debugging. - let mut cmd = Command::new("cargo"); - let cmd = cmd.arg("build").arg("--release"); - runner::forward_features(cmd); - cmd.current_dir(&base) - .stderr(process::Stdio::inherit()) - .stdout(process::Stdio::inherit()); - tracing::debug!("Running cargo command: {:?}", cmd); - - let output = cmd.output().expect("build output"); - let exit_code = output.status.code().unwrap_or(-1); - tracing::debug!("Cargo build exited with code {}", exit_code); - if !output.status.success() { - tracing::error!("Cargo build failed"); - process::exit(exit_code); - } - - let tests: Vec = test_cases - .into_iter() - .map(|case| { - let test_name = Runner::format_test_name(&case, &base); - TestDescAndFn { - desc: TestDesc { - name: DynTestName(test_name.clone()), - ignore: false, - should_panic: ShouldPanic::No, - allow_fail: false, - test_type: TestType::IntegrationTest, - }, - testfn: TestFn::DynTestFn(Box::new({ - let runner = runner.clone(); - move || { - runner - .run_test_case(&case) - .unwrap_or_else(|e| panic!("{}", e)); - } - })), - } - }) - .collect(); - - // If filters are provided that look like paths (contain '/'), convert them to test names - let opts = if opts.filters.iter().any(|f| f.contains('/')) { - let mut new_opts = opts; - new_opts.filters = new_opts - .filters - .into_iter() - .map(|filter| { - if filter.contains('/') { - // Convert path-like filter to test name format - filter.replace('/', "::") - } else { - filter - } - }) - .collect(); - new_opts - } else { - opts - }; - - let passed = run_tests_console(&opts, tests).expect("Failed to run tests"); - - process::exit(if passed { 0 } else { 1 }); -} diff --git a/tests/difftests/bin/src/test.rs b/tests/difftests/bin/src/test.rs new file mode 100644 index 0000000000..afa31a9c9c --- /dev/null +++ b/tests/difftests/bin/src/test.rs @@ -0,0 +1,6 @@ +use anyhow::Result; +use std::process::ExitCode; + +pub fn main() -> Result { + difftest_runner::run() +} diff --git a/tests/difftests/runner/Cargo.toml b/tests/difftests/runner/Cargo.toml new file mode 100644 index 0000000000..0919f7649d --- /dev/null +++ b/tests/difftests/runner/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "difftest-runner" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +# See rustc_codegen_spirv/Cargo.toml for details on these features +[features] +default = ["use-compiled-tools"] +use-installed-tools = [] +use-compiled-tools = [] + +[dependencies] +anyhow = "1.0" +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["fmt", "env-filter"] } +libtest-mimic = "0.8.1" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +thiserror = "1.0" +toml = { version = "0.8.20", default-features = false, features = ["parse"] } +bytesize = "2.0.1" +bytemuck = "1.21.0" +difftest-types = { path = "../types" } +tabled = { version = "0.15", default-features = false, features = ["std"] } + +[dev-dependencies] +tempfile = "3.5" + +[lints] +workspace = true diff --git a/tests/difftests/bin/src/differ.rs b/tests/difftests/runner/src/differ.rs similarity index 99% rename from tests/difftests/bin/src/differ.rs rename to tests/difftests/runner/src/differ.rs index 6b34b91e8a..35debea9d8 100644 --- a/tests/difftests/bin/src/differ.rs +++ b/tests/difftests/runner/src/differ.rs @@ -1,6 +1,6 @@ #![allow(clippy::unimplemented)] -use difftest::config::OutputType; +use difftest_types::config::OutputType; use std::marker::PhantomData; /// Represents the magnitude of a difference between two values diff --git a/tests/difftests/runner/src/lib.rs b/tests/difftests/runner/src/lib.rs new file mode 100644 index 0000000000..dab1cae295 --- /dev/null +++ b/tests/difftests/runner/src/lib.rs @@ -0,0 +1,75 @@ +#![allow(clippy::exit)] + +use crate::testcase::collect_test_dirs; +use anyhow::Result; +use libtest_mimic::{Arguments, Trial}; +use runner::Runner; +use std::process::ExitCode; +use std::sync::Arc; +use std::{ + env, fs, + process::{self}, +}; +use tracing_subscriber::FmtSubscriber; + +mod differ; +mod runner; +mod testcase; + +pub fn run() -> Result { + let mut args = Arguments::from_args(); + + // list must not print anything else to stdout + if !args.list { + let subscriber = FmtSubscriber::builder() + .with_env_filter(tracing_subscriber::EnvFilter::from_default_env()) + .finish(); + tracing::subscriber::set_global_default(subscriber) + .expect("Failed to set global subscriber"); + } + + // If filters are provided that look like paths (contain '/'), convert them to test names + if let Some(filter) = &mut args.filter { + *filter = filter.replace('/', "::"); + } + + let tests = collect_tests()?; + Ok(libtest_mimic::run(&args, tests).exit_code()) +} + +fn collect_tests() -> Result> { + // Find the manifest directory at compile time and locate tests in ../tests. + let manifest_dir = env!("CARGO_MANIFEST_DIR"); + let base = std::path::Path::new(manifest_dir) + .join("../tests") + .canonicalize() + .expect("Failed to canonicalize tests directory"); + tracing::debug!("Using tests directory: {}", base.display()); + + let output_dir = std::path::Path::new(manifest_dir).join("../tests/target/difftest"); + fs::create_dir_all(&output_dir)?; + let output_dir = output_dir + .canonicalize() + .expect("Failed to canonicalize tests directory"); + tracing::debug!("Using output directory: {}", output_dir.display()); + + let runner = Arc::new(Runner { + base_dir: base.clone(), + output_dir, + }); + + let test_cases = collect_test_dirs(&base).expect("Failed to collect test case directories"); + if test_cases.is_empty() { + eprintln!("No valid tests found in {}", base.display()); + process::exit(1); + } + + let trails = test_cases + .into_iter() + .map(|case| { + let runner = runner.clone(); + Trial::test(case.to_string(), move || Ok(runner.run_test_case(&case)?)) + }) + .collect(); + Ok(trails) +} diff --git a/tests/difftests/bin/src/runner.rs b/tests/difftests/runner/src/runner.rs similarity index 80% rename from tests/difftests/bin/src/runner.rs rename to tests/difftests/runner/src/runner.rs index 13738edcd2..917822b255 100644 --- a/tests/difftests/bin/src/runner.rs +++ b/tests/difftests/runner/src/runner.rs @@ -1,18 +1,18 @@ use bytesize::ByteSize; -use difftest::config::{OutputType, TestMetadata}; +use difftest_types::config::{OutputType, TestMetadata}; use serde::{Deserialize, Serialize}; +use std::process::Stdio; use std::{ collections::{HashMap, HashSet}, fs, - io::Write, - path::{Component, Path, PathBuf}, + path::{Path, PathBuf}, process::Command, }; -use tempfile::NamedTempFile; use thiserror::Error; use tracing::{debug, error, info, trace}; use crate::differ::{DiffMagnitude, Difference, DifferenceDisplay, OutputDiffer}; +use crate::testcase::TestCase; #[derive(Debug, Error)] pub enum RunnerError { @@ -214,65 +214,54 @@ impl ErrorReport { #[derive(Clone)] pub struct Runner { pub base_dir: PathBuf, + pub output_dir: PathBuf, } impl Runner { - pub fn new(base_dir: PathBuf) -> Self { - Self { base_dir } - } - - pub fn run_test_case(&self, test_case: &Path) -> RunnerResult<()> { - trace!("Starting test case: {}", test_case.display()); - let packages = self.collect_packages(test_case)?; + pub fn run_test_case(&self, test_case: &TestCase) -> RunnerResult<()> { + trace!("Starting test case: {}", test_case); debug!( "Found {} package(s) in test case {}", - packages.len(), - test_case.display() + test_case.test_binaries.len(), + test_case ); - if packages.len() < 2 { - error!("Insufficient packages in test case {}", test_case.display()); + if test_case.test_binaries.len() < 2 { + error!("Insufficient packages in test case {}", test_case); return Err(RunnerError::InsufficientPackages { - count: packages.len(), + count: test_case.test_binaries.len(), }); } // Pre-check that package names are globally unique. let mut names_seen = HashSet::new(); - for package in &packages { - let manifest_path = package.join("Cargo.toml"); + for package in &test_case.test_binaries { + let manifest_path = package.absolute_path.join("Cargo.toml"); let pkg_name = self.get_package_name(&manifest_path)?; if !names_seen.insert(pkg_name.clone()) { return Err(RunnerError::DuplicatePackageName { pkg_name }); } } - let mut temp_files: Vec = Vec::with_capacity(packages.len()); - let mut pkg_outputs: Vec = Vec::with_capacity(packages.len()); + let mut pkg_outputs: Vec = Vec::with_capacity(test_case.test_binaries.len()); let mut epsilon: Option = None; let mut output_type = None; - for package in packages { - trace!("Processing package at {}", package.display()); - let manifest_path = package.join("Cargo.toml"); + for package in &test_case.test_binaries { + trace!( + "Processing package '{}' at '{}'", + package, + package.absolute_path.display() + ); + let manifest_path = package.absolute_path.join("Cargo.toml"); let pkg_name = self.get_package_name(&manifest_path)?; debug!("Package '{}' detected", pkg_name); - let output_file = NamedTempFile::new()?; - let temp_output_path = output_file.path().to_path_buf(); - temp_files.push(output_file); - - let metadata_file = NamedTempFile::new()?; - let temp_metadata_path = metadata_file.path().to_path_buf(); - temp_files.push(metadata_file); - - trace!( - "Temporary output file created at {}", - temp_output_path.display() - ); - trace!( - "Temporary metadata file created at {}", - temp_metadata_path.display() - ); + let package_out = self.output_dir.join(&package.relative_path); + fs::create_dir_all(&package_out)?; + debug!("Writing output to '{}'", package_out.display()); + let config_file = package_out.join("config.json"); + let temp_output_path = package_out.join("out.bin"); + let temp_metadata_path = package_out.join("metadata.json"); let config = HarnessConfig { output_path: temp_output_path.clone(), @@ -280,9 +269,11 @@ impl Runner { }; let config_json = serde_json::to_string(&config) .map_err(|e| RunnerError::Config { msg: e.to_string() })?; - let mut config_file = NamedTempFile::new()?; - write!(config_file, "{config_json}").map_err(|e| RunnerError::Io { source: e })?; - trace!("Config file created at {}", config_file.path().display()); + fs::write(&config_file, &config_json)?; + trace!("Config file created at {}", config_file.display()); + + fs::write(&temp_output_path, [])?; + trace!("Output file created at {}", temp_output_path.display()); let mut cmd = Command::new("cargo"); cmd.arg("run").arg("--release").arg("--manifest-path").arg( @@ -293,18 +284,16 @@ impl Runner { })?, ); forward_features(&mut cmd); - cmd.arg("--").arg( - config_file - .path() - .to_str() - .ok_or_else(|| RunnerError::Config { - msg: "Invalid config file path".into(), - })?, - ); + cmd.arg("--") + .arg(config_file.to_str().ok_or_else(|| RunnerError::Config { + msg: "Invalid config file path".into(), + })?); debug!("Running cargo command: {:?}", cmd); let output = cmd - .current_dir(&package) + .current_dir(&package.absolute_path) + .stdout(Stdio::inherit()) + .stderr(Stdio::inherit()) .output() .map_err(|e| RunnerError::Io { source: e })?; let exit_code = output.status.code().unwrap_or(-1); @@ -317,7 +306,7 @@ impl Runner { error!("Cargo execution failed for package '{}'", pkg_name); return Err(RunnerError::CargoExecutionFailed { pkg_name, - package_path: package, + package_path: package.absolute_path.clone(), exit_status: exit_code, stderr: stderr_str, }); @@ -388,7 +377,7 @@ impl Runner { pkg_outputs.push(PackageOutput { pkg_name, - package_path: package, + package_path: package.absolute_path.clone(), output: output_bytes, temp_path: temp_output_path, }); @@ -424,30 +413,12 @@ impl Runner { // Generate detailed error report let details = self.format_error(&pkg_outputs, epsilon, output_type, &*differ, &*display); - self.keep_temp_files(&mut temp_files); return Err(RunnerError::DifferingOutput(details)); } - info!( - "Test case '{}' passed.", - Runner::format_test_name(test_case, test_case.parent().unwrap_or(test_case)) - ); + info!("Test case '{test_case}' passed."); Ok(()) } - #[allow(clippy::unused_self)] - fn collect_packages(&self, test_case: &Path) -> RunnerResult> { - let mut packages = Vec::new(); - for entry in fs::read_dir(test_case)? { - let entry = entry?; - let path = entry.path(); - if path.is_dir() && path.join("Cargo.toml").exists() { - debug!("Found package candidate: {}", path.display()); - packages.push(path); - } - } - Ok(packages) - } - #[allow(clippy::unused_self)] fn group_outputs<'a>( &self, @@ -665,64 +636,14 @@ impl Runner { debug!("Package name '{}' found in manifest", manifest.package.name); Ok(manifest.package.name) } - - #[allow(clippy::unused_self)] - fn keep_temp_files(&self, temp_files: &mut Vec) { - for file in temp_files.drain(..) { - let _ = file.into_temp_path().keep(); - } - } - - pub fn format_test_name(test_case: &Path, base: &Path) -> String { - let name = test_case.strip_prefix(base).map_or_else( - |_| test_case.to_string_lossy().into_owned(), - |relative| { - relative - .components() - .filter_map(|comp| match comp { - Component::Normal(os_str) => Some(os_str.to_string_lossy()), - _ => None, - }) - .collect::>() - .join("::") - }, - ); - format!("difftests::{name}") - } - - pub fn collect_test_dirs(root: &Path) -> RunnerResult> { - let mut test_cases = Vec::new(); - for entry in fs::read_dir(root)? { - let entry = entry?; - let path = entry.path(); - if path.is_dir() { - if Runner::collect_test_binaries(&path)?.len() >= 2 { - debug!("Test case found: {}", path.display()); - test_cases.push(path.clone()); - } - let mut subdirs = Runner::collect_test_dirs(&path)?; - test_cases.append(&mut subdirs); - } - } - Ok(test_cases) - } - - fn collect_test_binaries(test_case: &Path) -> RunnerResult> { - let mut packages = Vec::new(); - for entry in fs::read_dir(test_case)? { - let entry = entry?; - let path = entry.path(); - if path.is_dir() && path.join("Cargo.toml").exists() { - debug!("Found binary package candidate: {}", path.display()); - packages.push(path); - } - } - Ok(packages) - } } pub fn forward_features(cmd: &mut Command) { cmd.arg("--features"); + #[cfg(all(feature = "use-compiled-tools", feature = "use-installed-tools"))] + compile_error!( + "Features `use-compiled-tools` and `use-installed-tools` are mutually exclusive" + ); #[cfg(feature = "use-compiled-tools")] { cmd.arg("difftest/use-compiled-tools"); @@ -736,10 +657,17 @@ pub fn forward_features(cmd: &mut Command) { #[cfg(test)] mod tests { use super::*; - use difftest::config::OutputType; + use difftest_types::config::OutputType; use std::{fs, io::Write, path::Path, path::PathBuf}; use tempfile::{NamedTempFile, tempdir}; + fn dummy_runner() -> Runner { + Runner { + base_dir: PathBuf::from("dummy_base"), + output_dir: PathBuf::from("dummy_out"), + } + } + fn dummy_package_output(name: &str, path: &str, output: &[u8], temp: &str) -> PackageOutput { PackageOutput { pkg_name: name.to_string(), @@ -755,19 +683,11 @@ mod tests { let pkg2 = dummy_package_output("bar", "/path/to/bar", b"world", "tmp2"); let pkg3 = dummy_package_output("baz", "/path/to/baz", b"hello", "tmp3"); let outputs = vec![pkg1, pkg2, pkg3]; - let runner = Runner::new(PathBuf::from("dummy_base")); + let runner = dummy_runner(); let groups = runner.group_outputs(&outputs, None, OutputType::Raw); assert_eq!(groups.len(), 2); } - #[test] - fn test_format_test_name() { - let base = Path::new("/home/user/tests"); - let test_case = base.join("group1/testcase1"); - let formatted = Runner::format_test_name(&test_case, base); - assert_eq!(formatted, "difftests::group1::testcase1"); - } - #[test] fn test_get_package_name() { let mut temp = NamedTempFile::new().expect("failed to create temp file"); @@ -778,47 +698,13 @@ mod tests { edition = "2021" "#; write!(temp, "{cargo_toml}").expect("failed to write to temp file"); - let runner = Runner::new(PathBuf::from("dummy_base")); + let runner = dummy_runner(); let pkg_name = runner .get_package_name(temp.path()) .expect("failed to get package name"); assert_eq!(pkg_name, "dummy_package"); } - #[test] - fn test_collect_packages() { - let temp_dir = tempdir().expect("failed to create temp dir"); - let dir_path = temp_dir.path(); - let pkg_dir = dir_path.join("pkg1"); - fs::create_dir(&pkg_dir).expect("failed to create pkg1 dir"); - fs::write(pkg_dir.join("Cargo.toml"), "[package]\nname = \"pkg1\"") - .expect("failed to write Cargo.toml"); - let runner = Runner::new(PathBuf::from("dummy_base")); - let packages = runner - .collect_packages(dir_path) - .expect("failed to collect packages"); - assert_eq!(packages.len(), 1); - assert_eq!(packages[0], pkg_dir); - } - - #[test] - fn test_collect_test_dirs() { - let temp_dir = tempdir().expect("failed to create temp dir"); - let base = temp_dir.path(); - let test_case_dir = base.join("test_case"); - fs::create_dir(&test_case_dir).expect("failed to create test_case dir"); - let pkg1_dir = test_case_dir.join("pkg1"); - fs::create_dir(&pkg1_dir).expect("failed to create pkg1"); - fs::write(pkg1_dir.join("Cargo.toml"), "[package]\nname = \"pkg1\"") - .expect("failed to write Cargo.toml for pkg1"); - let pkg2_dir = test_case_dir.join("pkg2"); - fs::create_dir(&pkg2_dir).expect("failed to create pkg2"); - fs::write(pkg2_dir.join("Cargo.toml"), "[package]\nname = \"pkg2\"") - .expect("failed to write Cargo.toml for pkg2"); - let test_dirs = Runner::collect_test_dirs(base).expect("failed to collect test dirs"); - assert!(test_dirs.contains(&test_case_dir)); - } - #[test] fn test_run_test_case_insufficient_packages() { let temp_dir = tempdir().expect("failed to create temp dir"); @@ -828,8 +714,10 @@ mod tests { fs::create_dir(&pkg_dir).expect("failed to create pkg1"); fs::write(pkg_dir.join("Cargo.toml"), "[package]\nname = \"pkg1\"") .expect("failed to write Cargo.toml for pkg1"); - let runner = Runner::new(PathBuf::from("dummy_base")); - let result = runner.run_test_case(&test_case_dir); + let test_case = TestCase::try_new(temp_dir.path(), Path::new("single_pkg")) + .unwrap() + .unwrap(); + let result = dummy_runner().run_test_case(&test_case); match result { Err(RunnerError::InsufficientPackages { count }) => assert_eq!(count, 1), _ => panic!("Expected InsufficientPackages error"), @@ -849,8 +737,11 @@ mod tests { fs::create_dir(&pkg2_dir).expect("failed to create pkg2"); fs::write(pkg2_dir.join("Cargo.toml"), "[package]\nname = \"dup_pkg\"") .expect("failed to write Cargo.toml for pkg2"); - let runner = Runner::new(PathBuf::from("dummy_base")); - let result = runner.run_test_case(&test_case_dir); + let runner = dummy_runner(); + let test_case = TestCase::try_new(temp_dir.path(), Path::new("dup_pkg")) + .unwrap() + .unwrap(); + let result = runner.run_test_case(&test_case); match result { Err(RunnerError::DuplicatePackageName { pkg_name }) => assert_eq!(pkg_name, "dup_pkg"), _ => panic!("Expected DuplicatePackageName error"), @@ -948,7 +839,7 @@ mod tests { #[test] fn test_group_outputs_with_epsilon() { - let runner = Runner::new(PathBuf::from("dummy_base")); + let runner = dummy_runner(); // Create float outputs with small differences let val1: f32 = 1.0; @@ -977,8 +868,7 @@ mod tests { fn test_invalid_metadata_json() { // Test that invalid JSON in metadata file causes proper error let metadata_content = "{ invalid json }"; - let result: Result = - serde_json::from_str(metadata_content); + let result: Result = serde_json::from_str(metadata_content); assert!(result.is_err()); // Just check that it's an error, don't check the specific message } diff --git a/tests/difftests/runner/src/testcase.rs b/tests/difftests/runner/src/testcase.rs new file mode 100644 index 0000000000..9715abe25b --- /dev/null +++ b/tests/difftests/runner/src/testcase.rs @@ -0,0 +1,192 @@ +use crate::runner::RunnerResult; +use std::ffi::OsStr; +use std::fmt::{Display, Formatter}; +use std::fs; +use std::path::{Path, PathBuf}; +use tracing::debug; + +/// A test case containing multiple test binaries that should produce the same output +pub struct TestCase { + /// The name of the testcase, as a rust mod path + pub name: String, + /// the relative path from the base `difftest` dir + pub relative_path: PathBuf, + /// the absolute path + pub absolute_path: PathBuf, + /// All the test binaries of this single test case. + pub test_binaries: Vec, +} + +fn path_to_test_name(path: &Path) -> String { + path.to_string_lossy() + .replace("/", "::") + .replace("\\\\", "::") +} + +impl TestCase { + pub fn new_empty(root: &Path, relative_path: &Path) -> Self { + TestCase { + name: format!("difftests::{}", path_to_test_name(relative_path)), + absolute_path: root.join(relative_path), + relative_path: relative_path.to_path_buf(), + test_binaries: Vec::new(), + } + } + + pub fn try_new(root: &Path, relative_path: &Path) -> RunnerResult> { + let mut test_case = Self::new_empty(root, relative_path); + test_case.collect_test_binaries()?; + if !test_case.test_binaries.is_empty() { + debug!("Test case found: {}", relative_path.display()); + Ok(Some(test_case)) + } else { + Ok(None) + } + } + + fn collect_test_binaries(&mut self) -> RunnerResult<()> { + for entry in fs::read_dir(&self.absolute_path)? { + let entry = entry?; + let path = entry.path(); + let relative_path = self.relative_path.join(entry.file_name()); + if IGNORE_DIR_LIST + .iter() + .any(|dir| relative_path.as_os_str() == OsStr::new(dir)) + { + debug!("Ignoring test binary: {}", path.display()); + return Ok(()); + } + if path.is_dir() && path.join("Cargo.toml").exists() { + debug!("Found binary package candidate: {}", path.display()); + self.test_binaries + .push(TestBinary::new(self, Path::new(&entry.file_name()))); + } + } + Ok(()) + } +} + +impl Display for TestCase { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.name) + } +} + +/// A test binary that can be executed +pub struct TestBinary { + /// The name of the testcase, as a rust mod path + pub name: String, + /// the relative path from the base `difftest` dir + pub relative_path: PathBuf, + /// the absolute path + pub absolute_path: PathBuf, +} + +impl TestBinary { + pub fn new(test_case: &TestCase, relative_to_test_case: &Path) -> Self { + Self { + name: format!( + "{}::{}", + test_case.name, + path_to_test_name(relative_to_test_case) + ), + relative_path: test_case.relative_path.join(relative_to_test_case), + absolute_path: test_case.absolute_path.join(relative_to_test_case), + } + } +} + +impl Display for TestBinary { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.name) + } +} + +/// List of paths relative to `./tests/difftests/tests/` to ignore +pub const IGNORE_DIR_LIST: &[&str] = &["target", "lib"]; + +pub fn collect_test_dirs(root: &Path) -> RunnerResult> { + fn recurse(root: &Path, traverse: &Path, test_cases: &mut Vec) -> RunnerResult<()> { + let absolute_path = root.join(traverse); + if IGNORE_DIR_LIST + .iter() + .any(|dir| traverse.as_os_str() == OsStr::new(dir)) + { + debug!("Ignoring path: {}", absolute_path.display()); + return Ok(()); + } + + if let Some(test_case) = TestCase::try_new(root, traverse)? { + test_cases.push(test_case); + } + for entry in fs::read_dir(absolute_path)? { + let entry = entry?; + let path = entry.path(); + if path.is_dir() { + let relative_path = traverse.join(entry.file_name()); + recurse(root, &relative_path, test_cases)?; + } + } + Ok(()) + } + + let mut test_cases = Vec::new(); + recurse(root, Path::new(""), &mut test_cases)?; + Ok(test_cases) +} + +#[cfg(test)] +mod tests { + use super::*; + use tempfile::tempdir; + + #[test] + fn test_format_test_name() { + let mut test_case = + TestCase::new_empty(Path::new("/home/user/tests"), Path::new("core/group1")); + test_case + .test_binaries + .push(TestBinary::new(&test_case, Path::new("testcase1"))); + assert_eq!(test_case.to_string(), "difftests::core::group1"); + assert_eq!( + test_case.test_binaries[0].to_string(), + "difftests::core::group1::testcase1" + ); + } + + #[test] + fn test_collect_test_dirs() { + let temp_dir = tempdir().expect("failed to create temp dir"); + let base = temp_dir.path(); + let test_case_dir = base.join("test_case"); + fs::create_dir(&test_case_dir).expect("failed to create test_case dir"); + let pkg1_dir = test_case_dir.join("pkg1"); + fs::create_dir(&pkg1_dir).expect("failed to create pkg1"); + fs::write(pkg1_dir.join("Cargo.toml"), "[package]\nname = \"pkg1\"") + .expect("failed to write Cargo.toml for pkg1"); + let pkg2_dir = test_case_dir.join("pkg2"); + fs::create_dir(&pkg2_dir).expect("failed to create pkg2"); + fs::write(pkg2_dir.join("Cargo.toml"), "[package]\nname = \"pkg2\"") + .expect("failed to write Cargo.toml for pkg2"); + let mut test_dirs = collect_test_dirs(base).expect("failed to collect test dirs"); + + assert_eq!(test_dirs.len(), 1); + let test_case = &mut test_dirs[0]; + assert_eq!(test_case.relative_path.to_string_lossy(), "test_case"); + assert_eq!(test_case.absolute_path, test_case_dir); + + test_case + .test_binaries + .sort_by(|a, b| a.relative_path.cmp(&b.relative_path)); + assert_eq!( + test_case.test_binaries[0].relative_path, + Path::new("test_case/pkg1") + ); + assert_eq!(test_case.test_binaries[0].absolute_path, pkg1_dir); + assert_eq!( + test_case.test_binaries[1].relative_path, + Path::new("test_case/pkg2") + ); + assert_eq!(test_case.test_binaries[1].absolute_path, pkg2_dir); + } +} diff --git a/tests/difftests/tests/Cargo.lock b/tests/difftests/tests/Cargo.lock index a8238f3fea..6a532aa9ab 100644 --- a/tests/difftests/tests/Cargo.lock +++ b/tests/difftests/tests/Cargo.lock @@ -2,6 +2,34 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + [[package]] name = "allocator-api2" version = "0.2.21" @@ -23,6 +51,12 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +[[package]] +name = "ar" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69" + [[package]] name = "array_access-rust" version = "0.0.0" @@ -137,9 +171,9 @@ checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "bytemuck" -version = "1.22.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" +checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" dependencies = [ "bytemuck_derive", ] @@ -187,6 +221,17 @@ dependencies = [ "thiserror 2.0.12", ] +[[package]] +name = "cc" +version = "1.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -242,6 +287,12 @@ dependencies = [ "difftest", ] +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + [[package]] name = "core-foundation" version = "0.9.4" @@ -269,19 +320,42 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + [[package]] name = "crunchy" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn", +] + [[package]] name = "difftest" -version = "0.9.0" +version = "0.0.0" dependencies = [ "anyhow", "ash", "bytemuck", + "difftest-types", "futures", "naga", "serde", @@ -291,6 +365,16 @@ dependencies = [ "wgpu", ] +[[package]] +name = "difftest-types" +version = "0.9.0" +dependencies = [ + "anyhow", + "bytemuck", + "serde", + "serde_json", +] + [[package]] name = "document-features" version = "0.2.11" @@ -300,6 +384,22 @@ dependencies = [ "litrs", ] +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "elsa" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9abf33c656a7256451ebb7d0082c5a471820c31269e49d807c538c252352186e" +dependencies = [ + "indexmap", + "stable_deref_trait", +] + [[package]] name = "equivalent" version = "1.0.2" @@ -313,9 +413,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.59.0", ] +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + [[package]] name = "fastrand" version = "2.3.0" @@ -328,6 +434,16 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +[[package]] +name = "flate2" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "foldhash" version = "0.1.5" @@ -462,6 +578,17 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "gimli" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e1d97fbe9722ba9bbd0c97051c2956e726562b61f86a25a4360398a40edfc9" +dependencies = [ + "fallible-iterator", + "indexmap", + "stable_deref_trait", +] + [[package]] name = "gl_generator" version = "0.14.0" @@ -542,7 +669,7 @@ checksum = "dcf29e94d6d243368b7a56caa16bc213e4f9f8ed38c4d9557069527b5d5281ca" dependencies = [ "bitflags 2.9.0", "gpu-descriptor-types", - "hashbrown", + "hashbrown 0.15.2", ] [[package]] @@ -565,6 +692,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + [[package]] name = "hashbrown" version = "0.15.2" @@ -595,7 +732,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.2", +] + +[[package]] +name = "internal-iterator" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "969ee3fc68ec2e88eb21434ce4d9b7e1600d1ce92ff974560a6c4a304f5124b9" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", ] [[package]] @@ -610,6 +762,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.77" @@ -637,6 +798,12 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + [[package]] name = "libc" version = "0.2.171" @@ -659,6 +826,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "linux-raw-sys" version = "0.9.3" @@ -687,6 +860,12 @@ version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +[[package]] +name = "longest-increasing-subsequence" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" + [[package]] name = "mach-dxcompiler-rs" version = "0.1.4+2024.11.22-df583a3.1" @@ -702,6 +881,15 @@ dependencies = [ "libc", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "math_ops-rust" version = "0.0.0" @@ -772,6 +960,15 @@ dependencies = [ "paste", ] +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + [[package]] name = "naga" version = "25.0.1" @@ -784,7 +981,7 @@ dependencies = [ "cfg_aliases", "codespan-reporting", "half", - "hashbrown", + "hashbrown 0.15.2", "hexf-parse", "indexmap", "log", @@ -808,6 +1005,25 @@ dependencies = [ "jni-sys", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -827,6 +1043,21 @@ dependencies = [ "malloc_buf", ] +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "crc32fast", + "flate2", + "hashbrown 0.15.2", + "indexmap", + "memchr", + "ruzstd", + "wasmparser", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -842,6 +1073,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.3" @@ -878,7 +1115,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54acf3a685220b533e437e264e4d932cfbdc4cc7ec0cd232ed73c08d03b8a7ca" dependencies = [ "fixedbitset", - "hashbrown", + "hashbrown 0.15.2", "indexmap", "serde", ] @@ -990,6 +1227,50 @@ dependencies = [ "bitflags 2.9.0", ] +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + [[package]] name = "renderdoc-sys" version = "1.1.0" @@ -1006,12 +1287,52 @@ dependencies = [ "spirv", ] +[[package]] +name = "rustc-demangle" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" + [[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc_codegen_spirv" +version = "0.9.0" +dependencies = [ + "ahash", + "ar", + "bytemuck", + "either", + "indexmap", + "itertools", + "lazy_static", + "libc", + "log", + "object", + "regex", + "rspirv", + "rustc-demangle", + "rustc_codegen_spirv-target-specs", + "rustc_codegen_spirv-types", + "rustix 0.38.44", + "sanitize-filename", + "smallvec", + "spirt", + "spirv-tools", + "thorin-dwp", + "tracing", + "tracing-subscriber", + "tracing-tree", +] + +[[package]] +name = "rustc_codegen_spirv-target-specs" +version = "0.9.0" + [[package]] name = "rustc_codegen_spirv-types" version = "0.9.0" @@ -1022,6 +1343,30 @@ dependencies = [ "spirv", ] +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.9.0", + "errno", + "itoa", + "libc", + "linux-raw-sys 0.4.15", + "once_cell", + "windows-sys 0.59.0", +] + [[package]] name = "rustix" version = "1.0.2" @@ -1031,8 +1376,8 @@ dependencies = [ "bitflags 2.9.0", "errno", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.9.3", + "windows-sys 0.59.0", ] [[package]] @@ -1041,12 +1386,31 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +[[package]] +name = "ruzstd" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f" +dependencies = [ + "twox-hash", +] + [[package]] name = "ryu" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "sanitize-filename" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c502bdb638f1396509467cb0580ef3b29aa2a45c5d43e5d84928241280296c" +dependencies = [ + "lazy_static", + "regex", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -1094,6 +1458,21 @@ dependencies = [ "serde", ] +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "simple-compute-rust" version = "0.0.0" @@ -1132,6 +1511,30 @@ name = "smallvec" version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +dependencies = [ + "serde", +] + +[[package]] +name = "spirt" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2d5968bd2a36466468aac637b355776f080edfb0c6f769b2b99b9708260c42a" +dependencies = [ + "arrayvec", + "bytemuck", + "derive_more", + "elsa", + "indexmap", + "internal-iterator", + "itertools", + "lazy_static", + "longest-increasing-subsequence", + "rustc-hash", + "serde", + "serde_json", + "smallvec", +] [[package]] name = "spirv" @@ -1150,6 +1553,8 @@ dependencies = [ "cargo_metadata", "memchr", "raw-string", + "rustc_codegen_spirv", + "rustc_codegen_spirv-target-specs", "rustc_codegen_spirv-types", "semver", "serde", @@ -1183,6 +1588,32 @@ dependencies = [ name = "spirv-std-types" version = "0.9.0" +[[package]] +name = "spirv-tools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc3664e43ea7c03e2ed668bc0544c2b73dddd7a868eb93ccfcc64ee1deb1431e" +dependencies = [ + "memchr", + "spirv-tools-sys", + "tempfile", +] + +[[package]] +name = "spirv-tools-sys" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c95b52623ba771b5172dea9f04799928ce53ebc2ffc360c69d0fea3c3248d8" +dependencies = [ + "cc", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -1231,8 +1662,8 @@ dependencies = [ "fastrand", "getrandom", "once_cell", - "rustix", - "windows-sys", + "rustix 1.0.2", + "windows-sys 0.59.0", ] [[package]] @@ -1284,6 +1715,113 @@ dependencies = [ "syn", ] +[[package]] +name = "thorin-dwp" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "813ba76597db32dc4f6992fd8bf8f394715b88d352fd97401da67dab6283b4c6" +dependencies = [ + "gimli", + "hashbrown 0.14.5", + "object", + "tracing", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term 0.46.0", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "tracing-tree" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b56c62d2c80033cb36fae448730a2f2ef99410fe3ecbffc916681a32f6807dbe" +dependencies = [ + "nu-ansi-term 0.50.1", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + [[package]] name = "trig_ops-rust" version = "0.0.0" @@ -1299,6 +1837,16 @@ dependencies = [ "difftest", ] +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + [[package]] name = "unicode-ident" version = "1.0.18" @@ -1317,6 +1865,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + [[package]] name = "vector_extract_insert-rust" version = "0.0.0" @@ -1452,6 +2006,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasmparser" +version = "0.222.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa210fd1788e6b37a1d1930f3389c48e1d6ebd1a013d34fa4b7f9e3e3bf03146" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "web-sys" version = "0.3.77" @@ -1472,7 +2035,7 @@ dependencies = [ "bitflags 2.9.0", "cfg_aliases", "document-features", - "hashbrown", + "hashbrown 0.15.2", "js-sys", "log", "naga", @@ -1503,7 +2066,7 @@ dependencies = [ "bytemuck", "cfg_aliases", "document-features", - "hashbrown", + "hashbrown 0.15.2", "indexmap", "log", "naga", @@ -1570,7 +2133,7 @@ dependencies = [ "gpu-alloc", "gpu-allocator", "gpu-descriptor", - "hashbrown", + "hashbrown 0.15.2", "js-sys", "khronos-egl", "libc", @@ -1611,15 +2174,37 @@ dependencies = [ "web-sys", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys", + "windows-sys 0.59.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows" version = "0.58.0" @@ -1684,6 +2269,15 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.59.0" @@ -1797,3 +2391,23 @@ name = "xml-rs" version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4" + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/tests/difftests/tests/Cargo.toml b/tests/difftests/tests/Cargo.toml index 48449e6cc7..ad2b8924c1 100644 --- a/tests/difftests/tests/Cargo.toml +++ b/tests/difftests/tests/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "lib", "simple-compute/simple-compute-rust", "simple-compute/simple-compute-wgsl", "arch/atomic_ops/atomic_ops-rust", @@ -44,15 +45,18 @@ unexpected_cfgs = { level = "allow", check-cfg = [ 'cfg(target_arch, values("spirv"))' ] } +# Cargo Windows bug: workspace dependencies of crates.io dependencies are resolved +# incorrectly in the root workspace instead of this difftest workspace. So all +# workspace dependencies here must be mirrored into the root workspace as well. [workspace.dependencies] +spirv-builder = { path = "../../../crates/spirv-builder", default-features = false } spirv-std = { path = "../../../crates/spirv-std", version = "=0.9.0" } -spirv-std-types = { path = "../../../crates/spirv-std/shared", version = "=0.9.0" } -spirv-std-macros = { path = "../../../crates/spirv-std/macros", version = "=0.9.0" } -difftest = { path = "../../../tests/difftests/lib" } +difftest = { path = "lib" } +difftest-types = { path = "../types" } # External dependencies that need to be mentioned more than once. num-traits = { version = "0.2.15", default-features = false } -glam = { version = ">=0.22, <=0.29", default-features = false } -bytemuck = { version = "1.14", features = ["derive"] } +glam = { version = ">=0.22, <=0.30", default-features = false } +bytemuck = { version = "1.23", features = ["derive"] } # Enable incremental by default in release mode. [profile.release] diff --git a/tests/difftests/lib/Cargo.toml b/tests/difftests/tests/lib/Cargo.toml similarity index 87% rename from tests/difftests/lib/Cargo.toml rename to tests/difftests/tests/lib/Cargo.toml index c014741df6..01c714a52f 100644 --- a/tests/difftests/lib/Cargo.toml +++ b/tests/difftests/tests/lib/Cargo.toml @@ -1,10 +1,6 @@ [package] name = "difftest" -version.workspace = true -authors.workspace = true edition.workspace = true -license.workspace = true -repository.workspace = true # See rustc_codegen_spirv/Cargo.toml for details on these features [features] @@ -17,6 +13,7 @@ use-compiled-tools = [ [target.'cfg(not(target_arch = "spirv"))'.dependencies] spirv-builder.workspace = true +difftest-types.workspace = true serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" wgpu = { version = "25.0.2", features = ["spirv", "vulkan-portability", "static-dxc"] } diff --git a/tests/difftests/lib/src/lib.rs b/tests/difftests/tests/lib/src/lib.rs similarity index 97% rename from tests/difftests/lib/src/lib.rs rename to tests/difftests/tests/lib/src/lib.rs index 2f66926766..7491ec61f0 100644 --- a/tests/difftests/lib/src/lib.rs +++ b/tests/difftests/tests/lib/src/lib.rs @@ -1,7 +1,7 @@ #![cfg_attr(target_arch = "spirv", no_std)] #[cfg(not(target_arch = "spirv"))] -pub mod config; +pub use difftest_types::config; #[cfg(not(target_arch = "spirv"))] pub mod scaffold; diff --git a/tests/difftests/lib/src/scaffold/compute/ash.rs b/tests/difftests/tests/lib/src/scaffold/compute/ash.rs similarity index 100% rename from tests/difftests/lib/src/scaffold/compute/ash.rs rename to tests/difftests/tests/lib/src/scaffold/compute/ash.rs diff --git a/tests/difftests/lib/src/scaffold/compute/backend.rs b/tests/difftests/tests/lib/src/scaffold/compute/backend.rs similarity index 100% rename from tests/difftests/lib/src/scaffold/compute/backend.rs rename to tests/difftests/tests/lib/src/scaffold/compute/backend.rs diff --git a/tests/difftests/lib/src/scaffold/compute/mod.rs b/tests/difftests/tests/lib/src/scaffold/compute/mod.rs similarity index 100% rename from tests/difftests/lib/src/scaffold/compute/mod.rs rename to tests/difftests/tests/lib/src/scaffold/compute/mod.rs diff --git a/tests/difftests/lib/src/scaffold/compute/wgpu.rs b/tests/difftests/tests/lib/src/scaffold/compute/wgpu.rs similarity index 100% rename from tests/difftests/lib/src/scaffold/compute/wgpu.rs rename to tests/difftests/tests/lib/src/scaffold/compute/wgpu.rs diff --git a/tests/difftests/lib/src/scaffold/mod.rs b/tests/difftests/tests/lib/src/scaffold/mod.rs similarity index 100% rename from tests/difftests/lib/src/scaffold/mod.rs rename to tests/difftests/tests/lib/src/scaffold/mod.rs diff --git a/tests/difftests/lib/src/scaffold/shader/mod.rs b/tests/difftests/tests/lib/src/scaffold/shader/mod.rs similarity index 100% rename from tests/difftests/lib/src/scaffold/shader/mod.rs rename to tests/difftests/tests/lib/src/scaffold/shader/mod.rs diff --git a/tests/difftests/lib/src/scaffold/shader/rust_gpu_shader.rs b/tests/difftests/tests/lib/src/scaffold/shader/rust_gpu_shader.rs similarity index 100% rename from tests/difftests/lib/src/scaffold/shader/rust_gpu_shader.rs rename to tests/difftests/tests/lib/src/scaffold/shader/rust_gpu_shader.rs diff --git a/tests/difftests/lib/src/scaffold/shader/wgsl_shader.rs b/tests/difftests/tests/lib/src/scaffold/shader/wgsl_shader.rs similarity index 100% rename from tests/difftests/lib/src/scaffold/shader/wgsl_shader.rs rename to tests/difftests/tests/lib/src/scaffold/shader/wgsl_shader.rs diff --git a/tests/difftests/lib/src/scaffold/skip.rs b/tests/difftests/tests/lib/src/scaffold/skip.rs similarity index 100% rename from tests/difftests/lib/src/scaffold/skip.rs rename to tests/difftests/tests/lib/src/scaffold/skip.rs diff --git a/tests/difftests/types/Cargo.toml b/tests/difftests/types/Cargo.toml new file mode 100644 index 0000000000..25847165e6 --- /dev/null +++ b/tests/difftests/types/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "difftest-types" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true + +[lints] +workspace = true + +[dependencies] +anyhow = "1.0" +bytemuck = "1.21.0" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/tests/difftests/lib/src/config.rs b/tests/difftests/types/src/config.rs similarity index 73% rename from tests/difftests/lib/src/config.rs rename to tests/difftests/types/src/config.rs index 8107104668..78cfdd3dae 100644 --- a/tests/difftests/lib/src/config.rs +++ b/tests/difftests/types/src/config.rs @@ -1,3 +1,4 @@ +use anyhow::Context; use serde::{Deserialize, Serialize}; use std::fs::File; use std::io::Write; @@ -11,8 +12,18 @@ pub struct Config { impl Config { pub fn write_result(&self, output: &[A]) -> anyhow::Result<()> { - let mut f = File::create(&self.output_path)?; - f.write_all(bytemuck::cast_slice(output))?; + let mut f = File::create(&self.output_path).with_context(|| { + format!( + "failed to create output file '{}'", + self.output_path.display() + ) + })?; + f.write_all(bytemuck::cast_slice(output)).with_context(|| { + format!( + "failed to write to output file '{}'", + self.output_path.display() + ) + })?; Ok(()) } } @@ -106,15 +117,28 @@ impl TestMetadata { impl Config { pub fn from_path>(path: P) -> anyhow::Result { - let content = fs::read_to_string(path)?; - let config = serde_json::from_str(&content)?; + let path = path.as_ref(); + let content = fs::read_to_string(path) + .with_context(|| format!("Could not read file '{}'", path.display()))?; + let config = serde_json::from_str(&content).with_context(|| { + format!( + "Could not parse json in file '{}':\n{content}", + path.display() + ) + })?; Ok(config) } /// Write test metadata to the configured metadata path pub fn write_metadata(&self, metadata: &TestMetadata) -> anyhow::Result<()> { - let metadata_json = serde_json::to_string(metadata)?; - fs::write(&self.metadata_path, metadata_json)?; + let metadata_json = + serde_json::to_string(metadata).context("Could not serialize TestMetadata")?; + fs::write(&self.metadata_path, metadata_json).with_context(|| { + format!( + "Could not write TestMetadata to file at '{}'", + self.metadata_path.display() + ) + })?; Ok(()) } } diff --git a/tests/difftests/types/src/lib.rs b/tests/difftests/types/src/lib.rs new file mode 100644 index 0000000000..ef68c36943 --- /dev/null +++ b/tests/difftests/types/src/lib.rs @@ -0,0 +1 @@ +pub mod config;