Skip to content

Commit

Permalink
massive refactor of reproducible-build test
Browse files Browse the repository at this point in the history
  • Loading branch information
Oneirical committed Aug 7, 2024
1 parent 6f554ec commit 1da234c
Showing 1 changed file with 156 additions and 152 deletions.
308 changes: 156 additions & 152 deletions tests/run-make/reproducible-build/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// See https://github.com/rust-lang/rust/pull/32293

// FIXME(Oneirical): ignore-musl
// FIXME(Oneirical): two of these test blocks will apparently fail on windows
//@ ignore-windows
// FIXME(Oneirical): try it on test-various
// # FIXME: Builds of `bin` crate types are not deterministic with debuginfo=2 on
// # Windows.
Expand All @@ -30,193 +30,197 @@
use run_make_support::{bin_name, cwd, diff, rfs, run_in_tmpdir, rust_lib_name, rustc};

fn main() {
run_in_tmpdir(|| {
rustc().input("linker.rs").opt().run();
rustc().input("reproducible-build-aux.rs").run();
rustc()
.input("reproducible-build.rs")
.linker(&cwd().join(bin_name("linker")).display().to_string())
.run();
rustc()
.input("reproducible-build.rs")
.linker(&cwd().join(bin_name("linker")).display().to_string())
.run();
diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run();
});
// Smoke tests. Simple flags, build should be reproducible.
smoke_test(None);
smoke_test(Some(SmokeFlag::Debug));
smoke_test(Some(SmokeFlag::Opt));

run_in_tmpdir(|| {
rustc().input("linker.rs").opt().run();
rustc().arg("-g").input("reproducible-build-aux.rs").run();
rustc()
.arg("-g")
.input("reproducible-build.rs")
.linker(&cwd().join(bin_name("linker")).display().to_string())
.run();
rustc()
.arg("-g")
.input("reproducible-build.rs")
.linker(&cwd().join(bin_name("linker")).display().to_string())
.run();
diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run();
});
// Builds should be reproducible even through custom library search paths
// or remap path prefixes.
paths_test(PathsFlag::Link);
paths_test(PathsFlag::Remap);

run_in_tmpdir(|| {
rustc().input("linker.rs").opt().run();
rustc().opt().input("reproducible-build-aux.rs").run();
rustc()
.opt()
.input("reproducible-build.rs")
.linker(&cwd().join(bin_name("linker")).display().to_string())
.run();
rustc()
.opt()
.input("reproducible-build.rs")
.linker(&cwd().join(bin_name("linker")).display().to_string())
.run();
diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run();
});
// Builds should be reproducible even if each build is done in a different directory,
// with both --remap-path-prefix and -Z remap-cwd-prefix.

run_in_tmpdir(|| {
rustc().input("reproducible-build-aux.rs").run();
rustc().input("reproducible-build.rs").crate_type("rlib").library_search_path("b").run();
rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo"));
rustc().input("reproducible-build.rs").crate_type("rlib").library_search_path("a").run();
assert_eq!(rfs::read(rust_lib_name("reproducible_build")), rfs::read(rust_lib_name("foo")));
});
// FIXME(Oneirical): Building with crate type set to `bin` AND having -Cdebuginfo=2
// (or `-g`, the shorthand form) enabled will cause reproductibility failures.
// See https://github.com/rust-lang/rust/issues/89911

// This specific case would fail on OSX, should -Cdebuginfo=2 be added.
diff_dir_test(CrateType::Bin, RemapType::Path);

diff_dir_test(CrateType::Rlib, RemapType::Path);

//FIXME(Oneirical): This specific case would fail on both Linux and OSX, should -Cdebuginfo=2
// be added.
// See https://github.com/rust-lang/rust/issues/89911
diff_dir_test(CrateType::Bin, RemapType::Cwd { is_empty: false });

diff_dir_test(CrateType::Rlib, RemapType::Cwd { is_empty: false });
diff_dir_test(CrateType::Rlib, RemapType::Cwd { is_empty: true });

// Builds should be reproducible when using the --extern flag.
run_in_tmpdir(|| {
rustc().input("reproducible-build-aux.rs").run();
rustc()
.input("reproducible-build.rs")
.crate_type("rlib")
.arg("--remap-path-prefix=/a=/c")
.extern_("reproducible_build_aux", rust_lib_name("reproducible_build_aux"))
.run();
rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo"));
rfs::copy(rust_lib_name("reproducible_build_aux"), rust_lib_name("bar"));
rustc()
.input("reproducible-build.rs")
.crate_type("rlib")
.arg("--remap-path-prefix=/b=/c")
.extern_("reproducible_build_aux", rust_lib_name("bar"))
.run();
assert_eq!(rfs::read(rust_lib_name("reproducible_build")), rfs::read(rust_lib_name("foo")));
assert_eq!(rfs::read(rust_lib_name("foo")), rfs::read(rust_lib_name("reproducible_build")));
});
}

#[track_caller]
fn smoke_test(flag: Option<SmokeFlag>) {
run_in_tmpdir(|| {
rustc().input("linker.rs").opt().run();
rustc().input("reproducible-build-aux.rs").run();
rfs::create_dir("test");
rfs::copy("reproducible-build.rs", "test/reproducible-build.rs");
rustc()
let mut compiler1 = rustc();
let mut compiler2 = rustc();
if let Some(flag) = flag {
match flag {
SmokeFlag::Debug => {
compiler1.arg("-g");
compiler2.arg("-g");
}
SmokeFlag::Opt => {
compiler1.opt();
compiler2.opt();
}
};
};
compiler1
.input("reproducible-build.rs")
.crate_type("bin")
.arg(&format!("--remap-path-prefix={}=/b", cwd().display()))
.linker(&cwd().join(bin_name("linker")).display().to_string())
.run();
eprintln!("{:#?}", rfs::shallow_find_dir_entries(cwd()));
rfs::copy(bin_name("reproducible_build"), bin_name("foo"));
rustc()
.input("test/reproducible-build.rs")
.crate_type("bin")
.arg("--remap-path-prefix=/test=/b")
compiler2
.input("reproducible-build.rs")
.linker(&cwd().join(bin_name("linker")).display().to_string())
.run();
assert_eq!(rfs::read(bin_name("reproducible_build")), rfs::read(bin_name("foo")));
diff().actual_file("linker-arguments1").expected_file("linker-arguments2").run();
});
}

#[track_caller]
fn paths_test(flag: PathsFlag) {
run_in_tmpdir(|| {
rustc().input("reproducible-build-aux.rs").run();
rfs::create_dir("test");
rfs::copy("reproducible-build.rs", "test/reproducible-build.rs");
rustc()
.input("reproducible-build.rs")
.crate_type("rlib")
.arg(&format!("--remap-path-prefix={}=/b", cwd().display()))
.run();
rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo"));
rustc()
.input("test/reproducible-build.rs")
.crate_type("rlib")
.arg("--remap-path-prefix=/test=/b")
.run();
let mut compiler1 = rustc();
let mut compiler2 = rustc();
match flag {
PathsFlag::Link => {
compiler1.library_search_path("a");
compiler2.library_search_path("b");
}
PathsFlag::Remap => {
compiler1.arg("--remap-path-prefix=/a=/c");
compiler2.arg("--remap-path-prefix=/b=/c");
}
}
compiler1.input("reproducible-build.rs").crate_type("rlib").run();
rfs::rename(rust_lib_name("reproducible_build"), rust_lib_name("foo"));
compiler2.input("reproducible-build.rs").crate_type("rlib").run();
assert_eq!(rfs::read(rust_lib_name("reproducible_build")), rfs::read(rust_lib_name("foo")));
});
}

#[track_caller]
fn diff_dir_test(crate_type: CrateType, remap_type: RemapType) {
run_in_tmpdir(|| {
let base_dir = cwd();
rustc().input("reproducible-build-aux.rs").run();
rfs::create_dir("test");
rfs::copy("reproducible-build.rs", "test/reproducible-build.rs");
rustc()
let mut compiler1 = rustc();
let mut compiler2 = rustc();
match crate_type {
CrateType::Bin => {
compiler1.crate_type("bin");
compiler2.crate_type("bin");
}
CrateType::Rlib => {
compiler1.crate_type("rlib");
compiler2.crate_type("rlib");
}
}
match remap_type {
RemapType::Path => {
compiler1.arg(&format!("--remap-path-prefix={}=/b", cwd().display()));
compiler2
.arg(format!("--remap-path-prefix={}=/b", base_dir.join("test").display()));
}
RemapType::Cwd { is_empty } => {
// FIXME(Oneirical): Building with crate type set to `bin` AND having -Cdebuginfo=2
// (or `-g`, the shorthand form) enabled will cause reproductibility failures.
// See https://github.com/rust-lang/rust/issues/89911
if !matches!(crate_type, CrateType::Bin) {
compiler1.arg("-Cdebuginfo=2");
compiler2.arg("-Cdebuginfo=2");
}
if is_empty {
compiler1.arg("-Zremap-cwd-prefix=");
compiler2.arg("-Zremap-cwd-prefix=");
} else {
compiler1.arg("-Zremap-cwd-prefix=.");
compiler2.arg("-Zremap-cwd-prefix=.");
}
}
}
compiler1.input("reproducible-build.rs").run();
match crate_type {
CrateType::Bin => {
rfs::rename(bin_name("reproducible-build"), bin_name("foo"));
}
CrateType::Rlib => {
rfs::rename(rust_lib_name("reproducible_build"), rust_lib_name("foo"));
}
}
std::env::set_current_dir("test").unwrap();
compiler2
.input("reproducible-build.rs")
.crate_type("bin")
.arg("-Zremap-path-prefix=.")
.arg("-Cdebuginfo=2")
.run();
rfs::copy(bin_name("reproducible_build"), bin_name("first"));
rustc()
.input("test/reproducible-build.rs")
.crate_type("bin")
.arg("-Zremap-path-prefix=.")
.arg("-Cdebuginfo=2")
.run();
assert_eq!(rfs::read(bin_name("first")), rfs::read(bin_name("reproducible_build")));
.library_search_path(&base_dir)
.out_dir(&base_dir)
.run();
std::env::set_current_dir(&base_dir).unwrap();
match crate_type {
CrateType::Bin => {
assert!(rfs::read(bin_name("reproducible-build")) == rfs::read(bin_name("foo")));
}
CrateType::Rlib => {
assert_eq!(
rfs::read(rust_lib_name("foo")),
rfs::read(rust_lib_name("reproducible_build"))
);
}
}
});
}

run_in_tmpdir(|| {
rustc().input("reproducible-build-aux.rs").run();
rfs::create_dir("test");
rfs::copy("reproducible-build.rs", "test/reproducible-build.rs");
rustc()
.input("reproducible-build.rs")
.crate_type("rlib")
.arg("-Zremap-path-prefix=.")
.arg("-Cdebuginfo=2")
.run();
rfs::copy("reproducible_build", "first");
rustc()
.input("test/reproducible-build.rs")
.crate_type("rlib")
.arg("-Zremap-path-prefix=.")
.arg("-Cdebuginfo=2")
.run();
assert_eq!(
rfs::read(rust_lib_name("first")),
rfs::read(rust_lib_name("reproducible_build"))
);
});
enum SmokeFlag {
Debug,
Opt,
}

run_in_tmpdir(|| {
rustc().input("reproducible-build-aux.rs").run();
rfs::create_dir("test");
rfs::copy("reproducible-build.rs", "test/reproducible-build.rs");
rustc()
.input("reproducible-build.rs")
.crate_type("rlib")
.arg("-Zremap-path-prefix=")
.arg("-Cdebuginfo=2")
.run();
rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("first"));
rustc()
.input("test/reproducible-build.rs")
.crate_type("rlib")
.arg("-Zremap-path-prefix=")
.arg("-Cdebuginfo=2")
.run();
assert_eq!(
rfs::read(rust_lib_name("first")),
rfs::read(rust_lib_name("reproducible_build"))
);
});
enum PathsFlag {
Link,
Remap,
}

run_in_tmpdir(|| {
rustc().input("reproducible-build-aux.rs").run();
rustc()
.input("reproducible-build.rs")
.crate_type("rlib")
.extern_("reproducible_build_aux", rust_lib_name("reproducible_build_aux"))
.run();
rfs::copy(rust_lib_name("reproducible_build"), rust_lib_name("foo"));
rfs::copy(rust_lib_name("reproducible_build_aux"), rust_lib_name("bar"));
rustc()
.input("reproducible-build.rs")
.crate_type("rlib")
.extern_("reproducible_build_aux", rust_lib_name("bar"))
.run();
assert_eq!(rfs::read(rust_lib_name("foo")), rfs::read(rust_lib_name("reproducible_build")));
});
enum CrateType {
Bin,
Rlib,
}

enum RemapType {
Path,
Cwd { is_empty: bool },
}

0 comments on commit 1da234c

Please sign in to comment.