Skip to content

Commit b646f83

Browse files
authored
test(trim-paths): enable more tests for windows-msvc (#15621)
### What does this PR try to resolve? Before this some end-to-end tests didn't cover Windows platforms. After this, we cover windows-msvc for * End-to-end debugger tests. * Check path is trimmed with symbol viewers like `strings`. windows-gnu isn't covered ### How to test and review this PR? There are things needing attentions: * This adds a new CI job for window-msvc "nightly" toolchain. * In 2f923b3 we don't check if an executable's availability by running `<cmd> --version`. Instead, we check the file execute bit. * Enabled windows-msvc tests rely on the software provided by [GitHub windows runner image](https://github.com/actions/runner-images/blob/e330e24b7e154207c9d76ce3b5472bfc6ceef55f/images/windows/Windows2022-Readme.md) * Windows SDK which provides cdb and other debugger tools * `strings` is provided by MinGW.
2 parents 120ad80 + 4e50712 commit b646f83

File tree

3 files changed

+140
-12
lines changed

3 files changed

+140
-12
lines changed

.github/workflows/main.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,10 @@ jobs:
155155
os: windows-latest
156156
rust: stable-msvc
157157
other: i686-pc-windows-msvc
158+
- name: Windows x86_64 MSVC nightly
159+
os: windows-latest
160+
rust: nightly-msvc
161+
other: i686-pc-windows-msvc
158162
- name: Windows x86_64 gnu nightly # runs out of space while trying to link the test suite
159163
os: windows-latest
160164
rust: nightly-gnu
@@ -179,6 +183,10 @@ jobs:
179183
- run: sudo apt update -y && sudo apt install lldb gcc-multilib libsecret-1-0 libsecret-1-dev -y
180184
if: matrix.os == 'ubuntu-latest'
181185
- run: rustup component add rustfmt || echo "rustfmt not available"
186+
- name: Add Windows debuggers bin to PATH
187+
shell: pwsh
188+
run: Add-Content $env:GITHUB_PATH "C:\Program Files (x86)\Windows Kits\10\Debuggers\x64"
189+
if: matrix.os == 'windows-latest'
182190
- name: Configure extra test environment
183191
run: echo CARGO_CONTAINER_TESTS=1 >> $GITHUB_ENV
184192
if: matrix.os == 'ubuntu-latest'

crates/cargo-test-macro/src/lib.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,37 @@ fn check_command(command_path: &Path, args: &[&str]) -> bool {
302302
}
303303

304304
fn has_command(command: &str) -> bool {
305-
check_command(Path::new(command), &["--version"])
305+
use std::env::consts::EXE_EXTENSION;
306+
// ALLOWED: For testing cargo itself only.
307+
#[allow(clippy::disallowed_methods)]
308+
let Some(paths) = std::env::var_os("PATH") else {
309+
return false;
310+
};
311+
std::env::split_paths(&paths)
312+
.flat_map(|path| {
313+
let candidate = path.join(&command);
314+
let with_exe = if EXE_EXTENSION.is_empty() {
315+
None
316+
} else {
317+
Some(candidate.with_extension(EXE_EXTENSION))
318+
};
319+
std::iter::once(candidate).chain(with_exe)
320+
})
321+
.find(|p| is_executable(p))
322+
.is_some()
323+
}
324+
325+
#[cfg(unix)]
326+
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
327+
use std::os::unix::prelude::*;
328+
std::fs::metadata(path)
329+
.map(|metadata| metadata.is_file() && metadata.permissions().mode() & 0o111 != 0)
330+
.unwrap_or(false)
331+
}
332+
333+
#[cfg(windows)]
334+
fn is_executable<P: AsRef<Path>>(path: P) -> bool {
335+
path.as_ref().is_file()
306336
}
307337

308338
fn has_rustup_stable() -> bool {

tests/testsuite/profile_trim_paths.rs

Lines changed: 101 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -503,12 +503,32 @@ mod object_works {
503503
}
504504
}
505505

506-
#[cfg(unix)]
507-
fn object_works_helper(split_debuginfo: &str, run: impl Fn(&std::path::Path) -> Vec<u8>) {
508-
use std::os::unix::ffi::OsStrExt;
506+
#[cfg(target_env = "msvc")]
507+
mod object_works {
508+
use super::*;
509+
510+
fn inspect_debuginfo(path: &std::path::Path) -> Vec<u8> {
511+
std::process::Command::new("strings")
512+
.arg(path)
513+
.output()
514+
.expect("strings works")
515+
.stdout
516+
}
517+
518+
// windows-msvc supports split-debuginfo=packed only
519+
#[cargo_test(
520+
requires = "strings",
521+
nightly,
522+
reason = "-Zremap-path-scope is unstable"
523+
)]
524+
fn with_split_debuginfo_packed() {
525+
object_works_helper("packed", inspect_debuginfo);
526+
}
527+
}
509528

529+
fn object_works_helper(split_debuginfo: &str, run: impl Fn(&std::path::Path) -> Vec<u8>) {
510530
let registry_src = paths::home().join(".cargo/registry/src");
511-
let registry_src_bytes = registry_src.as_os_str().as_bytes();
531+
let registry_src_bytes = registry_src.as_os_str().as_encoded_bytes();
512532
let rust_src = "/lib/rustc/src/rust".as_bytes();
513533

514534
Package::new("bar", "0.0.1")
@@ -538,19 +558,27 @@ fn object_works_helper(split_debuginfo: &str, run: impl Fn(&std::path::Path) ->
538558
.build();
539559

540560
let pkg_root = p.root();
541-
let pkg_root = pkg_root.as_os_str().as_bytes();
561+
let pkg_root = pkg_root.as_os_str().as_encoded_bytes();
542562

543563
p.cargo("build").run();
544564

545565
let bin_path = p.bin("foo");
546566
assert!(bin_path.is_file());
547567
let stdout = run(&bin_path);
548-
// TODO: re-enable this check when rustc bootstrap disables remapping
549-
// <https://github.com/rust-lang/cargo/pull/12625#discussion_r1371714791>
550-
// assert!(memchr::memmem::find(&stdout, rust_src).is_some());
551-
assert!(memchr::memmem::find(&stdout, registry_src_bytes).is_some());
552-
assert!(memchr::memmem::find(&stdout, pkg_root).is_some());
553-
568+
// On windows-msvc every debuginfo is in pdb file, so can't find anything here.
569+
if cfg!(target_env = "msvc") {
570+
// TODO: re-enable this check when rustc bootstrap disables remapping
571+
// <https://github.com/rust-lang/cargo/pull/12625#discussion_r1371714791>
572+
// assert!(memchr::memmem::find(&stdout, rust_src).is_some());
573+
assert!(memchr::memmem::find(&stdout, registry_src_bytes).is_none());
574+
assert!(memchr::memmem::find(&stdout, pkg_root).is_none());
575+
} else {
576+
// TODO: re-enable this check when rustc bootstrap disables remapping
577+
// <https://github.com/rust-lang/cargo/pull/12625#discussion_r1371714791>
578+
// assert!(memchr::memmem::find(&stdout, rust_src).is_some());
579+
assert!(memchr::memmem::find(&stdout, registry_src_bytes).is_some());
580+
assert!(memchr::memmem::find(&stdout, pkg_root).is_some());
581+
}
554582
p.cargo("clean").run();
555583

556584
p.cargo("build --verbose -Ztrim-paths")
@@ -763,6 +791,68 @@ Hello, Ferris!
763791
);
764792
}
765793

794+
#[cfg(target_env = "msvc")]
795+
#[cargo_test(requires = "cdb", nightly, reason = "-Zremap-path-scope is unstable")]
796+
fn cdb_works_after_trimmed() {
797+
use cargo_test_support::compare::assert_e2e;
798+
799+
let run_debugger = |path| {
800+
std::process::Command::new("cdb")
801+
.args(["-c", "bp `main.rs:4`;g;g;q"])
802+
.arg(path)
803+
.output()
804+
.expect("debugger works")
805+
};
806+
807+
let p = project()
808+
.file(
809+
"Cargo.toml",
810+
r#"
811+
[package]
812+
name = "foo"
813+
version = "0.0.1"
814+
edition = "2015"
815+
816+
[profile.dev]
817+
trim-paths = "object"
818+
"#,
819+
)
820+
.file(
821+
"src/main.rs",
822+
r#"
823+
fn main() {
824+
let msg = "Hello, Ferris!";
825+
println!("{msg}");
826+
}
827+
"#,
828+
)
829+
.build();
830+
831+
p.cargo("build --verbose -Ztrim-paths")
832+
.masquerade_as_nightly_cargo(&["-Ztrim-paths"])
833+
.with_stderr_data(str![[r#"
834+
[COMPILING] foo v0.0.1 ([ROOT]/foo)
835+
[RUNNING] `rustc [..]-Zremap-path-scope=object --remap-path-prefix=[ROOT]/foo=. --remap-path-prefix=[..]/lib/rustlib/src/rust=/rustc/[..]`
836+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
837+
838+
"#]])
839+
.run();
840+
841+
let bin_path = p.bin("foo");
842+
assert!(bin_path.is_file());
843+
let stdout = String::from_utf8(run_debugger(bin_path).stdout).unwrap();
844+
assert_e2e().eq(
845+
&stdout,
846+
str![[r#"
847+
...
848+
Breakpoint 0 hit
849+
Hello, Ferris!
850+
...
851+
852+
"#]],
853+
);
854+
}
855+
766856
#[cargo_test(nightly, reason = "rustdoc --remap-path-prefix is unstable")]
767857
fn rustdoc_without_diagnostics_scope() {
768858
Package::new("bar", "0.0.1")

0 commit comments

Comments
 (0)