Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate link-arg, link-dedup and issue-26092 run-make tests to rmake format #125500

Merged
merged 3 commits into from
Jun 17, 2024
Merged
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
44 changes: 29 additions & 15 deletions src/tools/run-make-support/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::path::Path;
use std::process::{Command as StdCommand, ExitStatus, Output, Stdio};

use crate::drop_bomb::DropBomb;
use crate::{assert_contains, assert_not_contains, handle_failed_output};
use crate::{assert_contains, assert_equals, assert_not_contains, handle_failed_output};

/// This is a custom command wrapper that simplifies working with commands and makes it easier to
/// ensure that we check the exit status of executed processes.
Expand All @@ -21,6 +21,7 @@ use crate::{assert_contains, assert_not_contains, handle_failed_output};
///
/// [`run`]: Self::run
/// [`run_fail`]: Self::run_fail
/// [`run_unchecked`]: Self::run_unchecked
#[derive(Debug)]
pub struct Command {
cmd: StdCommand,
Expand Down Expand Up @@ -116,6 +117,15 @@ impl Command {
output
}

/// Run the command but do not check its exit status.
/// Only use if you explicitly don't care about the exit status.
/// Prefer to use [`Self::run`] and [`Self::run_fail`]
/// whenever possible.
#[track_caller]
pub fn run_unchecked(&mut self) -> CompletedProcess {
self.command_output()
}

#[track_caller]
fn command_output(&mut self) -> CompletedProcess {
self.drop_bomb.defuse();
Expand Down Expand Up @@ -163,41 +173,45 @@ impl CompletedProcess {
self.output.status
}

/// Checks that trimmed `stdout` matches trimmed `content`.
/// Checks that trimmed `stdout` matches trimmed `expected`.
#[track_caller]
pub fn assert_stdout_equals<S: AsRef<str>>(&self, content: S) -> &Self {
assert_eq!(self.stdout_utf8().trim(), content.as_ref().trim());
pub fn assert_stdout_equals<S: AsRef<str>>(&self, expected: S) -> &Self {
assert_equals(self.stdout_utf8().trim(), expected.as_ref().trim());
self
}

/// Checks that `stdout` does not contain `unexpected`.
#[track_caller]
pub fn assert_stdout_contains<S: AsRef<str>>(self, needle: S) -> Self {
assert_contains(&self.stdout_utf8(), needle.as_ref());
pub fn assert_stdout_not_contains<S: AsRef<str>>(&self, unexpected: S) -> &Self {
assert_not_contains(&self.stdout_utf8(), unexpected.as_ref());
self
}

/// Checks that `stdout` contains `expected`.
#[track_caller]
pub fn assert_stdout_not_contains<S: AsRef<str>>(&self, needle: S) -> &Self {
assert_not_contains(&self.stdout_utf8(), needle.as_ref());
pub fn assert_stdout_contains<S: AsRef<str>>(&self, expected: S) -> &Self {
assert_contains(&self.stdout_utf8(), expected.as_ref());
self
}

/// Checks that trimmed `stderr` matches trimmed `content`.
/// Checks that trimmed `stderr` matches trimmed `expected`.
#[track_caller]
pub fn assert_stderr_equals<S: AsRef<str>>(&self, content: S) -> &Self {
assert_eq!(self.stderr_utf8().trim(), content.as_ref().trim());
pub fn assert_stderr_equals<S: AsRef<str>>(&self, expected: S) -> &Self {
assert_equals(self.stderr_utf8().trim(), expected.as_ref().trim());
self
}

/// Checks that `stderr` contains `expected`.
#[track_caller]
pub fn assert_stderr_contains<S: AsRef<str>>(&self, needle: S) -> &Self {
assert_contains(&self.stderr_utf8(), needle.as_ref());
pub fn assert_stderr_contains<S: AsRef<str>>(&self, expected: S) -> &Self {
assert_contains(&self.stderr_utf8(), expected.as_ref());
self
}

/// Checks that `stderr` does not contain `unexpected`.
#[track_caller]
pub fn assert_stderr_not_contains<S: AsRef<str>>(&self, needle: S) -> &Self {
assert_not_contains(&self.stdout_utf8(), needle.as_ref());
pub fn assert_stderr_not_contains<S: AsRef<str>>(&self, unexpected: S) -> &Self {
assert_not_contains(&self.stdout_utf8(), unexpected.as_ref());
self
}

Expand Down
21 changes: 21 additions & 0 deletions src/tools/run-make-support/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,18 @@ pub fn read_dir<F: Fn(&Path)>(dir: impl AsRef<Path>, callback: F) {
}
}

/// Check that `actual` is equal to `expected`. Panic otherwise.
#[track_caller]
pub fn assert_equals(actual: &str, expected: &str) {
if actual != expected {
eprintln!("=== ACTUAL TEXT ===");
eprintln!("{}", actual);
eprintln!("=== EXPECTED ===");
eprintln!("{}", expected);
panic!("expected text was not found in actual text");
}
}

/// Check that `haystack` contains `needle`. Panic otherwise.
#[track_caller]
pub fn assert_contains(haystack: &str, needle: &str) {
Expand Down Expand Up @@ -468,6 +480,15 @@ macro_rules! impl_common_helpers {
self.cmd.run_fail()
}

/// Run the command but do not check its exit status.
/// Only use if you explicitly don't care about the exit status.
/// Prefer to use [`Self::run`] and [`Self::run_fail`]
/// whenever possible.
#[track_caller]
pub fn run_unchecked(&mut self) -> crate::command::CompletedProcess {
self.cmd.run_unchecked()
}

/// Set the path where the command will be run.
pub fn current_dir<P: AsRef<::std::path::Path>>(&mut self, path: P) -> &mut Self {
self.cmd.current_dir(path);
Expand Down
3 changes: 0 additions & 3 deletions src/tools/tidy/src/allowed_run_make_makefiles.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ run-make/issue-20626/Makefile
run-make/issue-22131/Makefile
run-make/issue-25581/Makefile
run-make/issue-26006/Makefile
run-make/issue-26092/Makefile
run-make/issue-28595/Makefile
run-make/issue-33329/Makefile
run-make/issue-35164/Makefile
Expand All @@ -109,10 +108,8 @@ run-make/libtest-json/Makefile
run-make/libtest-junit/Makefile
run-make/libtest-padding/Makefile
run-make/libtest-thread-limit/Makefile
run-make/link-arg/Makefile
run-make/link-args-order/Makefile
run-make/link-cfg/Makefile
run-make/link-dedup/Makefile
run-make/link-framework/Makefile
run-make/link-path-order/Makefile
run-make/linkage-attr-on-static/Makefile
Expand Down
1 change: 0 additions & 1 deletion tests/run-make/CURRENT_RUSTC_VERSION/rmake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ fn main() {

let output =
rustc().input("main.rs").emit("metadata").extern_("stable", "libstable.rmeta").run();

let version = fs_wrapper::read_to_string(source_root().join("src/version"));
let expected_string = format!("stable since {}", version.trim());
output.assert_stderr_contains(expected_string);
Expand Down
13 changes: 13 additions & 0 deletions tests/run-make/clear-error-blank-output/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// When an empty output file is passed to rustc, the ensuing error message
// should be clear. However, calling file_stem on an empty path returns None,
// which, when unwrapped, causes a panic, stopping execution of rustc
// and printing an obscure message instead of reaching the helpful
// error message. This test checks that the panic does not occur.
// See https://github.com/rust-lang/rust/pull/26199

use run_make_support::rustc;

fn main() {
let output = rustc().output("").stdin(b"fn main() {}").run_fail();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: I think this needs an .arg("-")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing it locally did not result in any problems.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool 😎

output.assert_stderr_not_contains("panic");
}
6 changes: 0 additions & 6 deletions tests/run-make/issue-26092/Makefile

This file was deleted.

5 changes: 0 additions & 5 deletions tests/run-make/link-arg/Makefile

This file was deleted.

20 changes: 20 additions & 0 deletions tests/run-make/link-arg/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// In 2016, the rustc flag "-C link-arg" was introduced - it can be repeatedly used
// to add single arguments to the linker. This test passes 2 arguments to the linker using it,
// then checks that the compiler's output contains the arguments passed to it.
// This ensures that the compiler successfully parses this flag.
// See https://github.com/rust-lang/rust/pull/36574

use run_make_support::rustc;

fn main() {
// We are only checking for the output of --print=link-args,
// rustc failing or succeeding does not matter.
let out = rustc()
.input("empty.rs")
.link_arg("-lfoo")
.link_arg("-lbar")
.print("link-args")
.run_unchecked();
out.assert_stdout_contains("lfoo");
out.assert_stdout_contains("lbar");
}
12 changes: 0 additions & 12 deletions tests/run-make/link-dedup/Makefile

This file was deleted.

24 changes: 24 additions & 0 deletions tests/run-make/link-dedup/rmake.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// When native libraries are passed to the linker, there used to be an annoyance
// where multiple instances of the same library in a row would cause duplication in
// outputs. This has been fixed, and this test checks that it stays fixed.
// With the --cfg flag, -ltestb gets added to the output, breaking up the chain of -ltesta.
// Without the --cfg flag, there should be a single -ltesta, no more, no less.
// See https://github.com/rust-lang/rust/pull/84794

//@ ignore-msvc

use run_make_support::rustc;

fn main() {
rustc().input("depa.rs").run();
rustc().input("depb.rs").run();
rustc().input("depc.rs").run();
let output = rustc().input("empty.rs").cfg("bar").run_fail();
output.assert_stderr_contains(r#""-ltesta" "-ltestb" "-ltesta""#);
let output = rustc().input("empty.rs").run_fail();
output.assert_stderr_contains(r#""-ltesta""#);
let output = rustc().input("empty.rs").run_fail();
output.assert_stderr_not_contains(r#""-ltestb""#);
let output = rustc().input("empty.rs").run_fail();
output.assert_stderr_not_contains(r#""-ltesta" "-ltesta" "-ltesta""#);
}
Loading