From cf6ba8db689f77045bf50123f9e0bca43e981a9d Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 26 Sep 2024 17:11:02 -0700 Subject: [PATCH 1/2] Use `CARGO_TARGET_TMPDIR` in integration tests Cargo 1.54 started setting this for integration tests, so that's a better place to use than just `target` as we were. I also moved most of the library tests to an integration test so they can use it too. --- src/tests.rs | 136 ------------------------------------------ tests/no_std.rs | 7 ++- tests/rustflags.rs | 13 ++-- tests/support/mod.rs | 21 +++++++ tests/tests.rs | 138 +++++++++++++++++++++++++++++++++++++++++++ tests/wrappers.rs | 10 ++-- 6 files changed, 175 insertions(+), 150 deletions(-) create mode 100644 tests/support/mod.rs create mode 100644 tests/tests.rs diff --git a/src/tests.rs b/src/tests.rs index c2468a6..19188c1 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,36 +1,5 @@ -use super::AutoCfg; -use std::env; use std::path::Path; -impl AutoCfg { - fn core_std(&self, path: &str) -> String { - let krate = if self.no_std { "core" } else { "std" }; - format!("{}::{}", krate, path) - } - - fn assert_std(&self, probe_result: bool) { - assert_eq!(!self.no_std, probe_result); - } - - fn assert_min(&self, major: usize, minor: usize, probe_result: bool) { - assert_eq!(self.probe_rustc_version(major, minor), probe_result); - } - - fn for_test() -> Result { - match env::var_os("TESTS_TARGET_DIR") { - Some(d) => Self::with_dir(d), - None => Self::with_dir("target"), - } - } -} - -#[test] -fn autocfg_version() { - let ac = AutoCfg::for_test().unwrap(); - println!("version: {:?}", ac.rustc_version); - assert!(ac.probe_rustc_version(1, 0)); -} - #[test] fn version_cmp() { use super::version::Version; @@ -44,111 +13,6 @@ fn version_cmp() { assert!(Version::new(2, 0, 0) > v123); } -#[test] -fn probe_add() { - let ac = AutoCfg::for_test().unwrap(); - let add = ac.core_std("ops::Add"); - let add_rhs = add.clone() + ""; - let add_rhs_output = add.clone() + ""; - let dyn_add_rhs_output = "dyn ".to_string() + &*add_rhs_output; - assert!(ac.probe_path(&add)); - assert!(ac.probe_trait(&add)); - assert!(ac.probe_trait(&add_rhs)); - assert!(ac.probe_trait(&add_rhs_output)); - ac.assert_min(1, 27, ac.probe_type(&dyn_add_rhs_output)); -} - -#[test] -fn probe_as_ref() { - let ac = AutoCfg::for_test().unwrap(); - let as_ref = ac.core_std("convert::AsRef"); - let as_ref_str = as_ref.clone() + ""; - let dyn_as_ref_str = "dyn ".to_string() + &*as_ref_str; - assert!(ac.probe_path(&as_ref)); - assert!(ac.probe_trait(&as_ref_str)); - assert!(ac.probe_type(&as_ref_str)); - ac.assert_min(1, 27, ac.probe_type(&dyn_as_ref_str)); -} - -#[test] -fn probe_i128() { - let ac = AutoCfg::for_test().unwrap(); - let i128_path = ac.core_std("i128"); - ac.assert_min(1, 26, ac.probe_path(&i128_path)); - ac.assert_min(1, 26, ac.probe_type("i128")); -} - -#[test] -fn probe_sum() { - let ac = AutoCfg::for_test().unwrap(); - let sum = ac.core_std("iter::Sum"); - let sum_i32 = sum.clone() + ""; - let dyn_sum_i32 = "dyn ".to_string() + &*sum_i32; - ac.assert_min(1, 12, ac.probe_path(&sum)); - ac.assert_min(1, 12, ac.probe_trait(&sum)); - ac.assert_min(1, 12, ac.probe_trait(&sum_i32)); - ac.assert_min(1, 12, ac.probe_type(&sum_i32)); - ac.assert_min(1, 27, ac.probe_type(&dyn_sum_i32)); -} - -#[test] -fn probe_std() { - let ac = AutoCfg::for_test().unwrap(); - ac.assert_std(ac.probe_sysroot_crate("std")); -} - -#[test] -fn probe_alloc() { - let ac = AutoCfg::for_test().unwrap(); - ac.assert_min(1, 36, ac.probe_sysroot_crate("alloc")); -} - -#[test] -fn probe_bad_sysroot_crate() { - let ac = AutoCfg::for_test().unwrap(); - assert!(!ac.probe_sysroot_crate("doesnt_exist")); -} - -#[test] -fn probe_no_std() { - let ac = AutoCfg::for_test().unwrap(); - assert!(ac.probe_type("i32")); - assert!(ac.probe_type("[i32]")); - ac.assert_std(ac.probe_type("Vec")); -} - -#[test] -fn probe_expression() { - let ac = AutoCfg::for_test().unwrap(); - assert!(ac.probe_expression(r#""test".trim_left()"#)); - ac.assert_min(1, 30, ac.probe_expression(r#""test".trim_start()"#)); - ac.assert_std(ac.probe_expression("[1, 2, 3].to_vec()")); -} - -#[test] -fn probe_constant() { - let ac = AutoCfg::for_test().unwrap(); - assert!(ac.probe_constant("1 + 2 + 3")); - ac.assert_min(1, 33, ac.probe_constant("{ let x = 1 + 2 + 3; x * x }")); - ac.assert_min(1, 39, ac.probe_constant(r#""test".len()"#)); -} - -#[test] -fn probe_raw() { - let ac = AutoCfg::for_test().unwrap(); - let prefix = if ac.no_std { "#![no_std]\n" } else { "" }; - let f = |s| format!("{}{}", prefix, s); - - // This attribute **must** be used at the crate level. - assert!(ac.probe_raw(&f("#![no_builtins]")).is_ok()); - - assert!(ac.probe_raw(&f("#![deny(dead_code)] fn x() {}")).is_err()); - assert!(ac.probe_raw(&f("#![allow(dead_code)] fn x() {}")).is_ok()); - assert!(ac - .probe_raw(&f("#![deny(dead_code)] pub fn x() {}")) - .is_ok()); -} - #[test] fn dir_does_not_contain_target() { assert!(!super::dir_contains_target( diff --git a/tests/no_std.rs b/tests/no_std.rs index 0a5dd58..05ab445 100644 --- a/tests/no_std.rs +++ b/tests/no_std.rs @@ -2,6 +2,8 @@ extern crate autocfg; use std::env; +mod support; + /// Tests that we can control the use of `#![no_std]`. #[test] fn no_std() { @@ -10,10 +12,9 @@ fn no_std() { env::remove_var("TARGET"); // Use the same path as this test binary. - let dir = env::current_exe().unwrap().parent().unwrap().to_path_buf(); - env::set_var("OUT_DIR", &format!("{}", dir.display())); + let out = support::out_dir(); - let mut ac = autocfg::AutoCfg::new().unwrap(); + let mut ac = autocfg::AutoCfg::with_dir(out.as_ref()).unwrap(); assert!(!ac.no_std()); assert!(ac.probe_path("std::mem")); diff --git a/tests/rustflags.rs b/tests/rustflags.rs index f054546..8038a0c 100644 --- a/tests/rustflags.rs +++ b/tests/rustflags.rs @@ -2,18 +2,19 @@ extern crate autocfg; use std::env; +mod support; + /// Tests that autocfg uses the RUSTFLAGS or CARGO_ENCODED_RUSTFLAGS /// environment variables when running rustc. #[test] fn test_with_sysroot() { - // Use the same path as this test binary. - let dir = env::current_exe().unwrap().parent().unwrap().to_path_buf(); - env::set_var("OUT_DIR", &format!("{}", dir.display())); + let dir = support::exe_dir(); + let out = support::out_dir(); // If we have encoded rustflags, they take precedence, even if empty. env::set_var("CARGO_ENCODED_RUSTFLAGS", ""); env::set_var("RUSTFLAGS", &format!("-L {}", dir.display())); - let ac = autocfg::AutoCfg::new().unwrap(); + let ac = autocfg::AutoCfg::with_dir(out.as_ref()).unwrap(); assert!(ac.probe_sysroot_crate("std")); assert!(!ac.probe_sysroot_crate("autocfg")); @@ -22,12 +23,12 @@ fn test_with_sysroot() { "CARGO_ENCODED_RUSTFLAGS", &format!("-L\x1f{}", dir.display()), ); - let ac = autocfg::AutoCfg::new().unwrap(); + let ac = autocfg::AutoCfg::with_dir(out.as_ref()).unwrap(); assert!(ac.probe_sysroot_crate("autocfg")); // Try the old-style RUSTFLAGS, ensuring HOST != TARGET. env::remove_var("CARGO_ENCODED_RUSTFLAGS"); env::set_var("HOST", "lol"); - let ac = autocfg::AutoCfg::new().unwrap(); + let ac = autocfg::AutoCfg::with_dir(out.as_ref()).unwrap(); assert!(ac.probe_sysroot_crate("autocfg")); } diff --git a/tests/support/mod.rs b/tests/support/mod.rs new file mode 100644 index 0000000..f50e717 --- /dev/null +++ b/tests/support/mod.rs @@ -0,0 +1,21 @@ +use std::borrow::Cow; +use std::env; +use std::path::{Path, PathBuf}; + +/// The directory containing this test binary. +pub fn exe_dir() -> PathBuf { + let exe = env::current_exe().unwrap(); + exe.parent().unwrap().to_path_buf() +} + +/// The directory to use for test probes. +pub fn out_dir() -> Cow<'static, Path> { + if let Some(tmpdir) = option_env!("CARGO_TARGET_TMPDIR") { + Cow::Borrowed(tmpdir.as_ref()) + } else if let Some(tmpdir) = env::var_os("TESTS_TARGET_DIR") { + Cow::Owned(tmpdir.into()) + } else { + // Use the same path as this test binary. + Cow::Owned(exe_dir()) + } +} diff --git a/tests/tests.rs b/tests/tests.rs new file mode 100644 index 0000000..de2b18c --- /dev/null +++ b/tests/tests.rs @@ -0,0 +1,138 @@ +extern crate autocfg; + +use autocfg::AutoCfg; + +mod support; + +fn core_std(ac: &AutoCfg, path: &str) -> String { + let krate = if ac.no_std() { "core" } else { "std" }; + format!("{}::{}", krate, path) +} + +fn assert_std(ac: &AutoCfg, probe_result: bool) { + assert_eq!(!ac.no_std(), probe_result); +} + +fn assert_min(ac: &AutoCfg, major: usize, minor: usize, probe_result: bool) { + assert_eq!(ac.probe_rustc_version(major, minor), probe_result); +} + +fn autocfg_for_test() -> AutoCfg { + AutoCfg::with_dir(support::out_dir().as_ref()).unwrap() +} + +#[test] +fn autocfg_version() { + let ac = autocfg_for_test(); + assert!(ac.probe_rustc_version(1, 0)); +} + +#[test] +fn probe_add() { + let ac = autocfg_for_test(); + let add = core_std(&ac, "ops::Add"); + let add_rhs = add.clone() + ""; + let add_rhs_output = add.clone() + ""; + let dyn_add_rhs_output = "dyn ".to_string() + &*add_rhs_output; + assert!(ac.probe_path(&add)); + assert!(ac.probe_trait(&add)); + assert!(ac.probe_trait(&add_rhs)); + assert!(ac.probe_trait(&add_rhs_output)); + assert_min(&ac, 1, 27, ac.probe_type(&dyn_add_rhs_output)); +} + +#[test] +fn probe_as_ref() { + let ac = autocfg_for_test(); + let as_ref = core_std(&ac, "convert::AsRef"); + let as_ref_str = as_ref.clone() + ""; + let dyn_as_ref_str = "dyn ".to_string() + &*as_ref_str; + assert!(ac.probe_path(&as_ref)); + assert!(ac.probe_trait(&as_ref_str)); + assert!(ac.probe_type(&as_ref_str)); + assert_min(&ac, 1, 27, ac.probe_type(&dyn_as_ref_str)); +} + +#[test] +fn probe_i128() { + let ac = autocfg_for_test(); + let i128_path = core_std(&ac, "i128"); + assert_min(&ac, 1, 26, ac.probe_path(&i128_path)); + assert_min(&ac, 1, 26, ac.probe_type("i128")); +} + +#[test] +fn probe_sum() { + let ac = autocfg_for_test(); + let sum = core_std(&ac, "iter::Sum"); + let sum_i32 = sum.clone() + ""; + let dyn_sum_i32 = "dyn ".to_string() + &*sum_i32; + assert_min(&ac, 1, 12, ac.probe_path(&sum)); + assert_min(&ac, 1, 12, ac.probe_trait(&sum)); + assert_min(&ac, 1, 12, ac.probe_trait(&sum_i32)); + assert_min(&ac, 1, 12, ac.probe_type(&sum_i32)); + assert_min(&ac, 1, 27, ac.probe_type(&dyn_sum_i32)); +} + +#[test] +fn probe_std() { + let ac = autocfg_for_test(); + assert_std(&ac, ac.probe_sysroot_crate("std")); +} + +#[test] +fn probe_alloc() { + let ac = autocfg_for_test(); + assert_min(&ac, 1, 36, ac.probe_sysroot_crate("alloc")); +} + +#[test] +fn probe_bad_sysroot_crate() { + let ac = autocfg_for_test(); + assert!(!ac.probe_sysroot_crate("doesnt_exist")); +} + +#[test] +fn probe_no_std() { + let ac = autocfg_for_test(); + assert!(ac.probe_type("i32")); + assert!(ac.probe_type("[i32]")); + assert_std(&ac, ac.probe_type("Vec")); +} + +#[test] +fn probe_expression() { + let ac = autocfg_for_test(); + assert!(ac.probe_expression(r#""test".trim_left()"#)); + assert_min(&ac, 1, 30, ac.probe_expression(r#""test".trim_start()"#)); + assert_std(&ac, ac.probe_expression("[1, 2, 3].to_vec()")); +} + +#[test] +fn probe_constant() { + let ac = autocfg_for_test(); + assert!(ac.probe_constant("1 + 2 + 3")); + assert_min( + &ac, + 1, + 33, + ac.probe_constant("{ let x = 1 + 2 + 3; x * x }"), + ); + assert_min(&ac, 1, 39, ac.probe_constant(r#""test".len()"#)); +} + +#[test] +fn probe_raw() { + let ac = autocfg_for_test(); + let prefix = if ac.no_std() { "#![no_std]\n" } else { "" }; + let f = |s| format!("{}{}", prefix, s); + + // This attribute **must** be used at the crate level. + assert!(ac.probe_raw(&f("#![no_builtins]")).is_ok()); + + assert!(ac.probe_raw(&f("#![deny(dead_code)] fn x() {}")).is_err()); + assert!(ac.probe_raw(&f("#![allow(dead_code)] fn x() {}")).is_ok()); + assert!(ac + .probe_raw(&f("#![deny(dead_code)] pub fn x() {}")) + .is_ok()); +} diff --git a/tests/wrappers.rs b/tests/wrappers.rs index 7ede12e..cacca71 100644 --- a/tests/wrappers.rs +++ b/tests/wrappers.rs @@ -2,6 +2,8 @@ extern crate autocfg; use std::env; +mod support; + /// Tests that autocfg uses the RUSTC_WRAPPER and/or RUSTC_WORKSPACE_WRAPPER /// environment variables when running rustc. #[test] @@ -15,9 +17,7 @@ fn test_wrappers() { } } - // Use the same path as this test binary. - let dir = env::current_exe().unwrap().parent().unwrap().to_path_buf(); - env::set_var("OUT_DIR", &format!("{}", dir.display())); + let out = support::out_dir(); // This is used as a heuristic to detect rust-lang/cargo#9601. env::set_var("CARGO_ENCODED_RUSTFLAGS", ""); @@ -30,7 +30,7 @@ fn test_wrappers() { set("RUSTC_WRAPPER", rustc); set("RUSTC_WORKSPACE_WRAPPER", workspace); - let ac = autocfg::AutoCfg::new().unwrap(); + let ac = autocfg::AutoCfg::with_dir(out.as_ref()).unwrap(); if rustc == Some(false) || workspace == Some(false) { // Everything should fail with bad wrappers. assert!(!ac.probe_type("usize")); @@ -48,7 +48,7 @@ fn test_wrappers() { // by using something that doesn't pass through at all. env::set_var("RUSTC_WRAPPER", "./tests/wrap_ignored"); env::set_var("RUSTC_WORKSPACE_WRAPPER", "/bin/false"); - let ac = autocfg::AutoCfg::new().unwrap(); + let ac = autocfg::AutoCfg::with_dir(out.as_ref()).unwrap(); assert!(ac.probe_type("mesize")); // anything goes! // Make sure we also got the version from that wrapper. From 42766ef4d09fdba1a3bd10b81833bc8cf1020dff Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 26 Sep 2024 17:27:14 -0700 Subject: [PATCH 2/2] Follow the exe for OUT_DIR in doc tests --- src/lib.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d9c6931..d117b9d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,7 +20,8 @@ //! //! fn main() { //! # // Normally, cargo will set `OUT_DIR` for build scripts. -//! # std::env::set_var("OUT_DIR", "target"); +//! # let exe = std::env::current_exe().unwrap(); +//! # std::env::set_var("OUT_DIR", exe.parent().unwrap()); //! let ac = autocfg::new(); //! ac.emit_has_type("i128"); //! @@ -297,7 +298,8 @@ impl AutoCfg { /// ``` /// # extern crate autocfg; /// # // Normally, cargo will set `OUT_DIR` for build scripts. - /// # std::env::set_var("OUT_DIR", "target"); + /// # let exe = std::env::current_exe().unwrap(); + /// # std::env::set_var("OUT_DIR", exe.parent().unwrap()); /// let ac = autocfg::new(); /// assert!(ac.probe_raw("#![no_builtins]").is_ok()); /// ``` @@ -312,7 +314,8 @@ impl AutoCfg { /// ``` /// # extern crate autocfg; /// # // Normally, cargo will set `OUT_DIR` for build scripts. - /// # std::env::set_var("OUT_DIR", "target"); + /// # let exe = std::env::current_exe().unwrap(); + /// # std::env::set_var("OUT_DIR", exe.parent().unwrap()); /// let ac = autocfg::new(); /// let code = r#" /// #![feature(slice_group_by)]