Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ members = [
exclude = [
# This currently needs to be excluded because it depends on a version of `rust-gpu` that
# uses a toolchain whose Cargo version doesn't recognise version 4 of `Cargo.lock`.
"crates/shader-crate-template"
"crates/shader-crate-template",
# Testing infra may copy the `shader-crate-template` into subdirs of target
"target",
]

resolver = "2"
Expand Down
1 change: 1 addition & 0 deletions crates/cargo-gpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ semver.workspace = true
dunce.workspace = true

[dev-dependencies]
tempfile.workspace = true
test-log.workspace = true
cargo_metadata = { workspace = true, features = ["builder"] }
cargo-util-schemas = "0.8.2"
Expand Down
2 changes: 0 additions & 2 deletions crates/cargo-gpu/src/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,6 @@ mod test {

#[test_log::test]
fn builder_from_params() {
crate::test::tests_teardown();

let shader_crate_path = crate::test::shader_crate_template_path();
let output_dir = shader_crate_path.join("shaders");

Expand Down
90 changes: 49 additions & 41 deletions crates/cargo-gpu/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,13 @@ impl Config {
mod test {
use super::*;

use crate::test::TestEnv;
use std::io::Write as _;

#[test_log::test]
fn booleans_from_cli() {
let shader_crate_path = crate::test::shader_crate_test_path();
let _env = TestEnv::new();
let shader_crate_path = _env.setup_shader_crate().unwrap();

let args = Config::clap_command_with_cargo_config(
&shader_crate_path,
Expand All @@ -108,43 +110,45 @@ mod test {

#[test_log::test]
fn booleans_from_cargo() {
let shader_crate_path = crate::test::shader_crate_test_path();
let mut file = crate::test::overwrite_shader_cargo_toml(&shader_crate_path);
file.write_all(
[
"[package.metadata.rust-gpu.build]",
"release = false",
"[package.metadata.rust-gpu.install]",
"auto-install-rust-toolchain = true",
]
.join("\n")
.as_bytes(),
)
.unwrap();
let _env = TestEnv::new();
let shader_crate_path = _env
.setup_shader_crate_with_cargo_toml(|file| {
file.write_all(
[
"[package.metadata.rust-gpu.build]",
"release = false",
"[package.metadata.rust-gpu.install]",
"auto-install-rust-toolchain = true",
]
.join("\n")
.as_bytes(),
)
})
.unwrap();

let args = Config::clap_command_with_cargo_config(&shader_crate_path, vec![]).unwrap();
assert!(!args.build.spirv_builder.release);
assert!(args.install.auto_install_rust_toolchain);
}

fn update_cargo_output_dir() -> std::path::PathBuf {
let shader_crate_path = crate::test::shader_crate_test_path();
let mut file = crate::test::overwrite_shader_cargo_toml(&shader_crate_path);
file.write_all(
[
"[package.metadata.rust-gpu.build]",
"output-dir = \"/the/moon\"",
]
.join("\n")
.as_bytes(),
)
.unwrap();
shader_crate_path
fn update_cargo_output_dir(_env: &TestEnv) -> std::path::PathBuf {
_env.setup_shader_crate_with_cargo_toml(|file| {
file.write_all(
[
"[package.metadata.rust-gpu.build]",
"output-dir = \"/the/moon\"",
]
.join("\n")
.as_bytes(),
)
})
.unwrap()
}

#[test_log::test]
fn string_from_cargo() {
let shader_crate_path = update_cargo_output_dir();
let _env = TestEnv::new();
let shader_crate_path = update_cargo_output_dir(&_env);

let args = Config::clap_command_with_cargo_config(&shader_crate_path, vec![]).unwrap();
if cfg!(target_os = "windows") {
Expand All @@ -156,7 +160,8 @@ mod test {

#[test_log::test]
fn string_from_cargo_overwritten_by_cli() {
let shader_crate_path = update_cargo_output_dir();
let _env = TestEnv::new();
let shader_crate_path = update_cargo_output_dir(&_env);

let args = Config::clap_command_with_cargo_config(
&shader_crate_path,
Expand All @@ -173,17 +178,19 @@ mod test {

#[test_log::test]
fn arrays_from_cargo() {
let shader_crate_path = crate::test::shader_crate_test_path();
let mut file = crate::test::overwrite_shader_cargo_toml(&shader_crate_path);
file.write_all(
[
"[package.metadata.rust-gpu.build]",
"capabilities = [\"AtomicStorage\", \"Matrix\"]",
]
.join("\n")
.as_bytes(),
)
.unwrap();
let _env = TestEnv::new();
let shader_crate_path = _env
.setup_shader_crate_with_cargo_toml(|file| {
file.write_all(
[
"[package.metadata.rust-gpu.build]",
"capabilities = [\"AtomicStorage\", \"Matrix\"]",
]
.join("\n")
.as_bytes(),
)
})
.unwrap();

let args = Config::clap_command_with_cargo_config(&shader_crate_path, vec![]).unwrap();
assert_eq!(
Expand All @@ -197,7 +204,8 @@ mod test {

#[test_log::test]
fn rename_manifest_parse() {
let shader_crate_path = crate::test::shader_crate_test_path();
let _env = TestEnv::new();
let shader_crate_path = _env.setup_shader_crate().unwrap();

let args = Config::clap_command_with_cargo_config(
&shader_crate_path,
Expand Down
19 changes: 7 additions & 12 deletions crates/cargo-gpu/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@
//! conduct other post-processing, like converting the `spv` files into `wgsl` files,
//! for example.

use anyhow::Context as _;

use crate::dump_usage::dump_full_usage_for_readme;
use build::Build;
use show::Show;
Expand Down Expand Up @@ -171,21 +169,18 @@ pub struct Cli {
/// # Errors
/// may fail if we can't find the user home directory
#[inline]
#[cfg(not(test))]
pub fn cache_dir() -> anyhow::Result<std::path::PathBuf> {
let dir = directories::BaseDirs::new()
use anyhow::Context as _;
Ok(directories::BaseDirs::new()
.with_context(|| "could not find the user home directory")?
.cache_dir()
.join("rust-gpu");

Ok(if cfg!(test) {
let thread_id = std::thread::current().id();
let id = format!("{thread_id:?}").replace('(', "-").replace(')', "");
dir.join("tests").join(id)
} else {
dir
})
.join("rust-gpu"))
}

#[cfg(test)]
pub use test::test_cache_dir as cache_dir;

/// Returns a string suitable to use as a directory.
///
/// Created from the spirv-builder source dep and the rustc channel.
Expand Down
6 changes: 4 additions & 2 deletions crates/cargo-gpu/src/spirv_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ pub fn get_channel_from_rustc_codegen_spirv_build_script(
#[cfg(test)]
mod test {
use super::*;
use crate::test::TestEnv;
use cargo_metadata::{PackageBuilder, PackageId, Source};
use cargo_util_schemas::manifest::PackageName;

Expand All @@ -259,7 +260,7 @@ mod test {
source,
SpirvSource::Git {
url: "https://github.com/Rust-GPU/rust-gpu".to_owned(),
rev: "86fc48032c4cd4afb74f1d81ae859711d20386a1".to_owned()
rev: "2aa4d4f8a8ba73103501562cfca17b8163e5a887".to_owned()
}
);
}
Expand All @@ -272,6 +273,7 @@ mod test {

#[test_log::test]
fn cached_checkout_dir_sanity() {
let _env = TestEnv::new();
let shader_template_path = crate::test::shader_crate_template_path();
let source = SpirvSource::get_rust_gpu_deps_from_shader(&shader_template_path).unwrap();
let dir = source.install_dir().unwrap();
Expand All @@ -281,7 +283,7 @@ mod test {
.to_str()
.map(std::string::ToString::to_string)
.unwrap();
assert_eq!("https___github_com_Rust-GPU_rust-gpu+86fc4803", &name);
assert_eq!("https___github_com_Rust-GPU_rust-gpu+2aa4d4f8", &name);
}

#[test_log::test]
Expand Down
102 changes: 74 additions & 28 deletions crates/cargo-gpu/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,80 @@
//! utilities for tests
#![cfg(test)]

use crate::cache_dir;
use anyhow::Context;
use std::cell::RefCell;
use std::fs::File;
use std::io::Write as _;
use std::path::PathBuf;
use tempfile::TempDir;

#[must_use]
pub struct TestEnv(TempDir);

impl TestEnv {
pub fn new() -> Self {
let target_dir = cargo_metadata::MetadataCommand::new()
.exec()
.unwrap()
.target_directory
.into_std_path_buf();
let tests_dir = target_dir.join("cargo-gpu-test");
std::fs::create_dir_all(&tests_dir).ok();
let test_dir = TempDir::new_in(tests_dir).unwrap();

let had_old = TESTDIR
.replace(Some(test_dir.path().to_path_buf()))
.is_some();
if had_old {
panic!("TestEnv is not reentrant!")
}

TestEnv(test_dir)
}

pub fn setup_shader_crate(&self) -> anyhow::Result<PathBuf> {
let shader_crate_path = crate::cache_dir().unwrap().join("shader_crate");
copy_dir_all(shader_crate_template_path(), &shader_crate_path)?;
Ok(shader_crate_path)
}

pub fn setup_shader_crate_with_cargo_toml(
&self,
f: impl FnOnce(&mut File) -> std::io::Result<()>,
) -> anyhow::Result<PathBuf> {
let shader_crate_path = self.setup_shader_crate()?;
let cargo_toml = shader_crate_path.join("Cargo.toml");
let mut file = std::fs::OpenOptions::new()
.write(true)
.truncate(true)
.open(cargo_toml)?;
writeln!(file, "[package]")?;
writeln!(file, "name = \"test\"")?;
f(&mut file)?;
Ok(shader_crate_path)
}
}

impl Drop for TestEnv {
fn drop(&mut self) {
TESTDIR.replace(None).unwrap();
// when a test fails, keep directory
if std::thread::panicking() {
self.0.disable_cleanup(true);
}
}
}

thread_local! {
static TESTDIR: RefCell<Option<PathBuf>> = RefCell::new(None);
}

/// [`crate::cache_dir`] for testing
pub fn test_cache_dir() -> anyhow::Result<PathBuf> {
Ok(TESTDIR.with_borrow(|a| a.clone()).context(
"TestEnv is not initialized! Add `let _env = TestEnv::new();` to the beginning of your test",
)?)
}

fn copy_dir_all(
src: impl AsRef<std::path::Path>,
Expand All @@ -21,33 +93,7 @@ fn copy_dir_all(
Ok(())
}

pub fn shader_crate_template_path() -> std::path::PathBuf {
pub fn shader_crate_template_path() -> PathBuf {
let project_base = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
project_base.join("../shader-crate-template")
}

pub fn shader_crate_test_path() -> std::path::PathBuf {
let shader_crate_path = crate::cache_dir().unwrap().join("shader_crate");
copy_dir_all(shader_crate_template_path(), shader_crate_path.clone()).unwrap();
shader_crate_path
}

pub fn overwrite_shader_cargo_toml(shader_crate_path: &std::path::Path) -> std::fs::File {
let cargo_toml = shader_crate_path.join("Cargo.toml");
let mut file = std::fs::OpenOptions::new()
.write(true)
.truncate(true)
.open(cargo_toml)
.unwrap();
writeln!(file, "[package]").unwrap();
writeln!(file, "name = \"test\"").unwrap();
file
}

pub fn tests_teardown() {
let cache_dir = cache_dir().unwrap();
if !cache_dir.exists() {
return;
}
std::fs::remove_dir_all(cache_dir).unwrap();
}
Loading
Loading