mirror of
				https://github.com/rust-lang/cargo.git
				synced 2025-11-03 13:12:53 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			303 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			303 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
//! A test suite for `-Zbuild-std` which is much more expensive than the
 | 
						|
//! standard test suite.
 | 
						|
//!
 | 
						|
//! This test suite attempts to perform a full integration test where we
 | 
						|
//! actually compile the standard library from source (like the real one) and
 | 
						|
//! the various tests associated with that.
 | 
						|
//!
 | 
						|
//! YOU SHOULD IDEALLY NOT WRITE TESTS HERE.
 | 
						|
//!
 | 
						|
//! If possible, use `tests/testsuite/standard_lib.rs` instead. That uses a
 | 
						|
//! 'mock' sysroot which is much faster to compile. The tests here are
 | 
						|
//! extremely intensive and are only intended to run on CI and are theoretically
 | 
						|
//! not catching any regressions that `tests/testsuite/standard_lib.rs` isn't
 | 
						|
//! already catching.
 | 
						|
//!
 | 
						|
//! All tests here should use `#[cargo_test(build_std_real)]` to indicate that
 | 
						|
//! boilerplate should be generated to require the nightly toolchain and the
 | 
						|
//! `CARGO_RUN_BUILD_STD_TESTS` env var to be set to actually run these tests.
 | 
						|
//! Otherwise the tests are skipped.
 | 
						|
 | 
						|
#![allow(clippy::disallowed_methods)]
 | 
						|
 | 
						|
use cargo_test_support::prelude::*;
 | 
						|
use cargo_test_support::{basic_manifest, paths, project, rustc_host, str, Execs};
 | 
						|
use std::env;
 | 
						|
use std::path::Path;
 | 
						|
 | 
						|
fn enable_build_std(e: &mut Execs, arg: Option<&str>) {
 | 
						|
    e.env_remove("CARGO_HOME");
 | 
						|
    e.env_remove("HOME");
 | 
						|
 | 
						|
    // And finally actually enable `build-std` for now
 | 
						|
    let arg = match arg {
 | 
						|
        Some(s) => format!("-Zbuild-std={}", s),
 | 
						|
        None => "-Zbuild-std".to_string(),
 | 
						|
    };
 | 
						|
    e.arg(arg).arg("-Zpublic-dependency");
 | 
						|
    e.masquerade_as_nightly_cargo(&["build-std"]);
 | 
						|
}
 | 
						|
 | 
						|
// Helper methods used in the tests below
 | 
						|
trait BuildStd: Sized {
 | 
						|
    fn build_std(&mut self) -> &mut Self;
 | 
						|
    fn build_std_arg(&mut self, arg: &str) -> &mut Self;
 | 
						|
    fn target_host(&mut self) -> &mut Self;
 | 
						|
}
 | 
						|
 | 
						|
impl BuildStd for Execs {
 | 
						|
    fn build_std(&mut self) -> &mut Self {
 | 
						|
        enable_build_std(self, None);
 | 
						|
        self
 | 
						|
    }
 | 
						|
 | 
						|
    fn build_std_arg(&mut self, arg: &str) -> &mut Self {
 | 
						|
        enable_build_std(self, Some(arg));
 | 
						|
        self
 | 
						|
    }
 | 
						|
 | 
						|
    fn target_host(&mut self) -> &mut Self {
 | 
						|
        self.arg("--target").arg(rustc_host());
 | 
						|
        self
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#[cargo_test(build_std_real)]
 | 
						|
fn basic() {
 | 
						|
    let p = project()
 | 
						|
        .file(
 | 
						|
            "src/main.rs",
 | 
						|
            "
 | 
						|
                fn main() {
 | 
						|
                    foo::f();
 | 
						|
                }
 | 
						|
 | 
						|
                #[test]
 | 
						|
                fn smoke_bin_unit() {
 | 
						|
                    foo::f();
 | 
						|
                }
 | 
						|
            ",
 | 
						|
        )
 | 
						|
        .file(
 | 
						|
            "src/lib.rs",
 | 
						|
            "
 | 
						|
                extern crate alloc;
 | 
						|
                extern crate proc_macro;
 | 
						|
 | 
						|
                /// ```
 | 
						|
                /// foo::f();
 | 
						|
                /// ```
 | 
						|
                pub fn f() {
 | 
						|
                }
 | 
						|
 | 
						|
                #[test]
 | 
						|
                fn smoke_lib_unit() {
 | 
						|
                    f();
 | 
						|
                }
 | 
						|
            ",
 | 
						|
        )
 | 
						|
        .file(
 | 
						|
            "tests/smoke.rs",
 | 
						|
            "
 | 
						|
                #[test]
 | 
						|
                fn smoke_integration() {
 | 
						|
                    foo::f();
 | 
						|
                }
 | 
						|
            ",
 | 
						|
        )
 | 
						|
        .build();
 | 
						|
 | 
						|
    p.cargo("check").build_std().target_host().run();
 | 
						|
    p.cargo("build")
 | 
						|
        .build_std()
 | 
						|
        .target_host()
 | 
						|
        // Importantly, this should not say [UPDATING]
 | 
						|
        // There have been multiple bugs where every build triggers and update.
 | 
						|
        .with_stderr_data(str![[r#"
 | 
						|
[COMPILING] foo v0.0.1 ([ROOT]/foo)
 | 
						|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
 | 
						|
 | 
						|
"#]])
 | 
						|
        .run();
 | 
						|
    p.cargo("run")
 | 
						|
        .build_std()
 | 
						|
        .target_host()
 | 
						|
        .with_stderr_data(str![[r#"
 | 
						|
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
 | 
						|
[RUNNING] `target/[HOST_TARGET]/debug/foo`
 | 
						|
 | 
						|
"#]])
 | 
						|
        .run();
 | 
						|
    p.cargo("test")
 | 
						|
        .build_std()
 | 
						|
        .target_host()
 | 
						|
        .with_stderr_data(str![[r#"
 | 
						|
[COMPILING] rustc-std-workspace-std [..]
 | 
						|
...
 | 
						|
[COMPILING] test v0.0.0 ([..])
 | 
						|
[COMPILING] foo v0.0.1 ([ROOT]/foo)
 | 
						|
[FINISHED] `test` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
 | 
						|
[RUNNING] unittests src/lib.rs (target/[HOST_TARGET]/debug/deps/foo-[HASH])
 | 
						|
[RUNNING] unittests src/main.rs (target/[HOST_TARGET]/debug/deps/foo-[HASH])
 | 
						|
[RUNNING] tests/smoke.rs (target/[HOST_TARGET]/debug/deps/smoke-[HASH])
 | 
						|
[DOCTEST] foo
 | 
						|
 | 
						|
"#]])
 | 
						|
        .run();
 | 
						|
 | 
						|
    // Check for hack that removes dylibs.
 | 
						|
    let deps_dir = Path::new("target")
 | 
						|
        .join(rustc_host())
 | 
						|
        .join("debug")
 | 
						|
        .join("deps");
 | 
						|
    assert!(p.glob(deps_dir.join("*.rlib")).count() > 0);
 | 
						|
    assert_eq!(p.glob(deps_dir.join("*.dylib")).count(), 0);
 | 
						|
}
 | 
						|
 | 
						|
#[cargo_test(build_std_real)]
 | 
						|
fn cross_custom() {
 | 
						|
    let p = project()
 | 
						|
        .file(
 | 
						|
            "Cargo.toml",
 | 
						|
            r#"
 | 
						|
                [package]
 | 
						|
                name = "foo"
 | 
						|
                version = "0.1.0"
 | 
						|
                edition = "2018"
 | 
						|
 | 
						|
                [target.custom-target.dependencies]
 | 
						|
                dep = { path = "dep" }
 | 
						|
            "#,
 | 
						|
        )
 | 
						|
        .file(
 | 
						|
            "src/lib.rs",
 | 
						|
            "#![no_std] pub fn f() -> u32 { dep::answer() }",
 | 
						|
        )
 | 
						|
        .file("dep/Cargo.toml", &basic_manifest("dep", "0.1.0"))
 | 
						|
        .file("dep/src/lib.rs", "#![no_std] pub fn answer() -> u32 { 42 }")
 | 
						|
        .file(
 | 
						|
            "custom-target.json",
 | 
						|
            r#"
 | 
						|
            {
 | 
						|
                "llvm-target": "x86_64-unknown-none-gnu",
 | 
						|
                "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
 | 
						|
                "arch": "x86_64",
 | 
						|
                "target-endian": "little",
 | 
						|
                "target-pointer-width": "64",
 | 
						|
                "target-c-int-width": "32",
 | 
						|
                "os": "none",
 | 
						|
                "linker-flavor": "ld.lld"
 | 
						|
            }
 | 
						|
            "#,
 | 
						|
        )
 | 
						|
        .build();
 | 
						|
 | 
						|
    p.cargo("build --target custom-target.json -v")
 | 
						|
        .build_std_arg("core")
 | 
						|
        .run();
 | 
						|
}
 | 
						|
 | 
						|
#[cargo_test(build_std_real)]
 | 
						|
fn custom_test_framework() {
 | 
						|
    let p = project()
 | 
						|
        .file(
 | 
						|
            "src/lib.rs",
 | 
						|
            r#"
 | 
						|
            #![no_std]
 | 
						|
            #![cfg_attr(test, no_main)]
 | 
						|
            #![feature(custom_test_frameworks)]
 | 
						|
            #![test_runner(crate::test_runner)]
 | 
						|
 | 
						|
            pub fn test_runner(_tests: &[&dyn Fn()]) {}
 | 
						|
 | 
						|
            #[panic_handler]
 | 
						|
            fn panic(_info: &core::panic::PanicInfo) -> ! {
 | 
						|
                loop {}
 | 
						|
            }
 | 
						|
            "#,
 | 
						|
        )
 | 
						|
        .file(
 | 
						|
            "target.json",
 | 
						|
            r#"
 | 
						|
            {
 | 
						|
                "llvm-target": "x86_64-unknown-none-gnu",
 | 
						|
                "data-layout": "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128",
 | 
						|
                "arch": "x86_64",
 | 
						|
                "target-endian": "little",
 | 
						|
                "target-pointer-width": "64",
 | 
						|
                "target-c-int-width": "32",
 | 
						|
                "os": "none",
 | 
						|
                "linker-flavor": "ld.lld",
 | 
						|
                "linker": "rust-lld",
 | 
						|
                "executables": true,
 | 
						|
                "panic-strategy": "abort"
 | 
						|
            }
 | 
						|
            "#,
 | 
						|
        )
 | 
						|
        .build();
 | 
						|
 | 
						|
    // This is a bit of a hack to use the rust-lld that ships with most toolchains.
 | 
						|
    let sysroot = paths::sysroot();
 | 
						|
    let sysroot = Path::new(&sysroot);
 | 
						|
    let sysroot_bin = sysroot
 | 
						|
        .join("lib")
 | 
						|
        .join("rustlib")
 | 
						|
        .join(rustc_host())
 | 
						|
        .join("bin");
 | 
						|
    let path = env::var_os("PATH").unwrap_or_default();
 | 
						|
    let mut paths = env::split_paths(&path).collect::<Vec<_>>();
 | 
						|
    paths.insert(0, sysroot_bin);
 | 
						|
    let new_path = env::join_paths(paths).unwrap();
 | 
						|
 | 
						|
    p.cargo("test --target target.json --no-run -v")
 | 
						|
        .env("PATH", new_path)
 | 
						|
        .build_std_arg("core")
 | 
						|
        .run();
 | 
						|
}
 | 
						|
 | 
						|
// Fixing rust-lang/rust#117839.
 | 
						|
// on macOS it never gets remapped.
 | 
						|
// Might be a separate issue, so only run on Linux.
 | 
						|
#[cargo_test(build_std_real)]
 | 
						|
#[cfg(target_os = "linux")]
 | 
						|
fn remap_path_scope() {
 | 
						|
    let p = project()
 | 
						|
        .file(
 | 
						|
            "src/main.rs",
 | 
						|
            "
 | 
						|
                fn main() {
 | 
						|
                    panic!(\"remap to /rustc/<hash>\");
 | 
						|
                }
 | 
						|
            ",
 | 
						|
        )
 | 
						|
        .file(
 | 
						|
            ".cargo/config.toml",
 | 
						|
            "
 | 
						|
                [profile.release]
 | 
						|
                debug = \"line-tables-only\"
 | 
						|
            ",
 | 
						|
        )
 | 
						|
        .build();
 | 
						|
 | 
						|
    p.cargo("run --release -Ztrim-paths")
 | 
						|
        .masquerade_as_nightly_cargo(&["-Ztrim-paths"])
 | 
						|
        .env("RUST_BACKTRACE", "1")
 | 
						|
        .build_std()
 | 
						|
        .target_host()
 | 
						|
        .with_status(101)
 | 
						|
        .with_stderr_data(
 | 
						|
            str![[r#"
 | 
						|
[FINISHED] `release` profile [optimized + debuginfo] target(s) in [ELAPSED]s
 | 
						|
[RUNNING] `target/[HOST_TARGET]/release/foo`
 | 
						|
[..]thread '[..]' panicked at [..]src/main.rs:3:[..]:
 | 
						|
remap to /rustc/<hash>
 | 
						|
             at /rustc/[..]/library/std/src/[..]
 | 
						|
             at ./src/main.rs:3:[..]
 | 
						|
             at /rustc/[..]/library/core/src/[..]
 | 
						|
...
 | 
						|
"#]]
 | 
						|
            .unordered(),
 | 
						|
        )
 | 
						|
        .run();
 | 
						|
}
 |