about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-08-05 12:16:05 +0000
committerbors <bors@rust-lang.org>2024-08-05 12:16:05 +0000
commit83e9b93c90bcd7f52d17d09b52e3a2eff707c46a (patch)
tree1d72f2a58d9d671d9fea2feff10763238308d53e /tests
parent9179d9b334e3f5e8772e1a563308dc95a1cde960 (diff)
parent94da7b157a5ebcde7ee23f4bd2041307e579891f (diff)
Auto merge of #127095 - Oneirical:testiary-education, r=jieyouxu
Migrate `reproducible-build-2` and `stable-symbol-names` `run-make` tests to rmake

Part of #121876 and the associated [Google Summer of Code project](https://blog.rust-lang.org/2024/05/01/gsoc-2024-selected-projects.html).

Needs try-jobs.

try-job: x86_64-msvc
try-job: armhf-gnu
try-job: test-various
try-job: aarch64-apple
try-job: i686-msvc
try-job: x86_64-mingw
Diffstat (limited to 'tests')
-rw-r--r--tests/run-make/reproducible-build-2/Makefile27
-rw-r--r--tests/run-make/reproducible-build-2/rmake.rs47
-rw-r--r--tests/run-make/stable-symbol-names/Makefile41
-rw-r--r--tests/run-make/stable-symbol-names/rmake.rs68
4 files changed, 115 insertions, 68 deletions
diff --git a/tests/run-make/reproducible-build-2/Makefile b/tests/run-make/reproducible-build-2/Makefile
deleted file mode 100644
index 68fcac8b47f..00000000000
--- a/tests/run-make/reproducible-build-2/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-# ignore-musl
-# ignore-windows
-# Objects are reproducible but their path is not.
-
-all:  \
-	fat_lto \
-	sysroot
-
-fat_lto:
-	rm -rf $(TMPDIR) && mkdir $(TMPDIR)
-	$(RUSTC) reproducible-build-aux.rs
-	$(RUSTC) reproducible-build.rs -C lto=fat
-	cp $(TMPDIR)/reproducible-build $(TMPDIR)/reproducible-build-a
-	$(RUSTC) reproducible-build.rs -C lto=fat
-	cmp "$(TMPDIR)/reproducible-build-a" "$(TMPDIR)/reproducible-build" || exit 1
-
-sysroot:
-	rm -rf $(TMPDIR) && mkdir $(TMPDIR)
-	$(RUSTC) reproducible-build-aux.rs
-	$(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(shell $(RUSTC) --print sysroot) --remap-path-prefix=$(shell $(RUSTC) --print sysroot)=/sysroot
-	cp -R $(shell $(RUSTC) --print sysroot) $(TMPDIR)/sysroot
-	cp $(TMPDIR)/libreproducible_build.rlib $(TMPDIR)/libfoo.rlib
-	$(RUSTC) reproducible-build.rs --crate-type rlib --sysroot $(TMPDIR)/sysroot --remap-path-prefix=$(TMPDIR)/sysroot=/sysroot
-	cmp "$(TMPDIR)/libreproducible_build.rlib" "$(TMPDIR)/libfoo.rlib" || exit 1
diff --git a/tests/run-make/reproducible-build-2/rmake.rs b/tests/run-make/reproducible-build-2/rmake.rs
new file mode 100644
index 00000000000..c500c4238b0
--- /dev/null
+++ b/tests/run-make/reproducible-build-2/rmake.rs
@@ -0,0 +1,47 @@
+// Builds with fat link-time-optimizations and the --sysroot flag used to be
+// non-deterministic - that means, compiling twice with no changes would create
+// slightly different outputs. This has been fixed by #63352 and #63505.
+// Test 1: Compile with fat-lto twice, check that both compilation outputs are identical.
+// Test 2: Compile with sysroot, then change the sysroot path from absolute to relative.
+// Outputs should be identical.
+// See https://github.com/rust-lang/rust/issues/34902
+
+//@ ignore-windows
+// Reasons:
+// 1. The object files are reproducible, but their paths are not, which causes
+// the first assertion in the test to fail.
+// 2. When the sysroot gets copied, some symlinks must be re-created,
+// which is a privileged action on Windows.
+
+use run_make_support::{bin_name, rfs, rust_lib_name, rustc};
+
+fn main() {
+    // test 1: fat lto
+    rustc().input("reproducible-build-aux.rs").run();
+    rustc().input("reproducible-build.rs").arg("-Clto=fat").output("reproducible-build").run();
+    rfs::rename("reproducible-build", "reproducible-build-a");
+    rustc().input("reproducible-build.rs").arg("-Clto=fat").output("reproducible-build").run();
+    assert_eq!(rfs::read("reproducible-build"), rfs::read("reproducible-build-a"));
+
+    // test 2: sysroot
+    let sysroot = rustc().print("sysroot").run().stdout_utf8();
+    let sysroot = sysroot.trim();
+
+    rustc().input("reproducible-build-aux.rs").run();
+    rustc()
+        .input("reproducible-build.rs")
+        .crate_type("rlib")
+        .sysroot(&sysroot)
+        .arg(format!("--remap-path-prefix={sysroot}=/sysroot"))
+        .run();
+    rfs::copy_dir_all(&sysroot, "sysroot");
+    rfs::rename(rust_lib_name("reproducible_build"), rust_lib_name("foo"));
+    rustc()
+        .input("reproducible-build.rs")
+        .crate_type("rlib")
+        .sysroot("sysroot")
+        .arg("--remap-path-prefix=/sysroot=/sysroot")
+        .run();
+
+    assert_eq!(rfs::read(rust_lib_name("reproducible_build")), rfs::read(rust_lib_name("foo")));
+}
diff --git a/tests/run-make/stable-symbol-names/Makefile b/tests/run-make/stable-symbol-names/Makefile
deleted file mode 100644
index bbfb8e38881..00000000000
--- a/tests/run-make/stable-symbol-names/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-include ../tools.mk
-
-# The following command will:
-#  1. dump the symbols of a library using `nm`
-#  2. extract only those lines that we are interested in via `grep`
-#  3. from those lines, extract just the symbol name via `sed`, which:
-#    * always starts with "_ZN" and ends with "E" (`legacy` mangling)
-#    * always starts with "_R" (`v0` mangling)
-#  4. sort those symbol names for deterministic comparison
-#  5. write the result into a file
-
-dump-symbols = nm "$(TMPDIR)/lib$(1).rlib" \
-             | grep -E "$(2)" \
-             | sed -E "s/.*(_ZN.*E|_R[a-zA-Z0-9_]*).*/\1/" \
-             | sort \
-             > "$(TMPDIR)/$(1)$(3).nm"
-
-# This test
-# - compiles each of the two crates 2 times and makes sure each time we get
-#   exactly the same symbol names
-# - makes sure that both crates agree on the same symbol names for monomorphic
-#   functions
-
-all:
-	$(RUSTC) stable-symbol-names1.rs
-	$(call dump-symbols,stable_symbol_names1,generic_|mono_,_v1)
-	rm $(TMPDIR)/libstable_symbol_names1.rlib
-	$(RUSTC) stable-symbol-names1.rs
-	$(call dump-symbols,stable_symbol_names1,generic_|mono_,_v2)
-	cmp "$(TMPDIR)/stable_symbol_names1_v1.nm" "$(TMPDIR)/stable_symbol_names1_v2.nm"
-
-	$(RUSTC) stable-symbol-names2.rs
-	$(call dump-symbols,stable_symbol_names2,generic_|mono_,_v1)
-	rm $(TMPDIR)/libstable_symbol_names2.rlib
-	$(RUSTC) stable-symbol-names2.rs
-	$(call dump-symbols,stable_symbol_names2,generic_|mono_,_v2)
-	cmp "$(TMPDIR)/stable_symbol_names2_v1.nm" "$(TMPDIR)/stable_symbol_names2_v2.nm"
-
-	$(call dump-symbols,stable_symbol_names1,mono_,_cross)
-	$(call dump-symbols,stable_symbol_names2,mono_,_cross)
-	cmp "$(TMPDIR)/stable_symbol_names1_cross.nm" "$(TMPDIR)/stable_symbol_names2_cross.nm"
diff --git a/tests/run-make/stable-symbol-names/rmake.rs b/tests/run-make/stable-symbol-names/rmake.rs
new file mode 100644
index 00000000000..402f411c7f5
--- /dev/null
+++ b/tests/run-make/stable-symbol-names/rmake.rs
@@ -0,0 +1,68 @@
+// A typo in rustc caused generic symbol names to be non-deterministic -
+// that is, it was possible to compile the same file twice with no changes
+// and get outputs with different symbol names.
+// This test compiles each of the two crates twice, and checks that each output
+// contains exactly the same symbol names.
+// Additionally, both crates should agree on the same symbol names for monomorphic
+// functions.
+// See https://github.com/rust-lang/rust/issues/32554
+
+use std::collections::HashSet;
+
+use run_make_support::{llvm_readobj, regex, rfs, rust_lib_name, rustc};
+
+static LEGACY_PATTERN: std::sync::OnceLock<regex::Regex> = std::sync::OnceLock::new();
+static V0_PATTERN: std::sync::OnceLock<regex::Regex> = std::sync::OnceLock::new();
+
+fn main() {
+    LEGACY_PATTERN.set(regex::Regex::new(r"_ZN.*E").unwrap()).unwrap();
+    V0_PATTERN.set(regex::Regex::new(r"_R[a-zA-Z0-9_]*").unwrap()).unwrap();
+    // test 1: first file
+    rustc().input("stable-symbol-names1.rs").run();
+    let sym1 = process_symbols("stable_symbol_names1", "generic_|mono_");
+    rfs::remove_file(rust_lib_name("stable_symbol_names1"));
+    rustc().input("stable-symbol-names1.rs").run();
+    let sym2 = process_symbols("stable_symbol_names1", "generic_|mono_");
+    assert_eq!(sym1, sym2);
+
+    // test 2: second file
+    rustc().input("stable-symbol-names2.rs").run();
+    let sym1 = process_symbols("stable_symbol_names2", "generic_|mono_");
+    rfs::remove_file(rust_lib_name("stable_symbol_names2"));
+    rustc().input("stable-symbol-names2.rs").run();
+    let sym2 = process_symbols("stable_symbol_names2", "generic_|mono_");
+    assert_eq!(sym1, sym2);
+
+    // test 3: crossed files
+    let sym1 = process_symbols("stable_symbol_names1", "mono_");
+    let sym2 = process_symbols("stable_symbol_names2", "mono_");
+    assert_eq!(sym1, sym2);
+}
+
+#[track_caller]
+fn process_symbols(path: &str, symbol: &str) -> Vec<String> {
+    // Dump all symbols.
+    let out = llvm_readobj().input(rust_lib_name(path)).symbols().run().stdout_utf8();
+    // Extract only lines containing `symbol`.
+    let symbol_regex = regex::Regex::new(symbol).unwrap();
+    let out = out.lines().filter(|&line| symbol_regex.find(line).is_some());
+
+    // HashSet - duplicates should be excluded!
+    let mut symbols: HashSet<String> = HashSet::new();
+    // From those lines, extract just the symbol name via `regex`, which:
+    //   * always starts with "_ZN" and ends with "E" (`legacy` mangling)
+    //   * always starts with "_R" (`v0` mangling)
+    for line in out {
+        if let Some(mat) = LEGACY_PATTERN.get().unwrap().find(line) {
+            symbols.insert(mat.as_str().to_string());
+        }
+        if let Some(mat) = V0_PATTERN.get().unwrap().find(line) {
+            symbols.insert(mat.as_str().to_string());
+        }
+    }
+
+    let mut symbols: Vec<String> = symbols.into_iter().collect();
+    // Sort those symbol names for deterministic comparison.
+    symbols.sort();
+    symbols
+}