From 8c93de6a827952ab1341e28be923a2aab221f3c7 Mon Sep 17 00:00:00 2001 From: Dario Gonzalez Date: Fri, 26 Apr 2019 14:05:37 -0700 Subject: [PATCH 1/3] Added ability to crosscompile doctests --- src/cargo/core/compiler/compilation.rs | 2 +- src/cargo/ops/cargo_test.rs | 18 +++++++++++++----- tests/testsuite/cross_compile.rs | 7 +++++-- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/cargo/core/compiler/compilation.rs b/src/cargo/core/compiler/compilation.rs index dcd2e1923bf..35dc7e26656 100644 --- a/src/cargo/core/compiler/compilation.rs +++ b/src/cargo/core/compiler/compilation.rs @@ -163,7 +163,7 @@ impl<'cfg> Compilation<'cfg> { self.fill_env(process(cmd), pkg, true) } - fn target_runner(&self) -> &Option<(PathBuf, Vec)> { + pub fn target_runner(&self) -> &Option<(PathBuf, Vec)> { &self.target_runner } diff --git a/src/cargo/ops/cargo_test.rs b/src/cargo/ops/cargo_test.rs index 1079df47efa..0bb3a65c687 100644 --- a/src/cargo/ops/cargo_test.rs +++ b/src/cargo/ops/cargo_test.rs @@ -140,10 +140,7 @@ fn run_doc_tests( let mut errors = Vec::new(); let config = options.compile_opts.config; - // We don't build/run doc tests if `target` does not equal `host`. - if compilation.host != compilation.target { - return Ok((Test::Doc, errors)); - } + let runtool = compilation.target_runner(); for doctest_info in &compilation.to_doc_test { let Doctest { @@ -158,6 +155,18 @@ fn run_doc_tests( .arg("--crate-name") .arg(&target.crate_name()); + p.arg("-Z"); + p.arg("unstable-options"); + p.arg("--enable-per-target-ignores"); + + runtool.as_ref().map(|(runtool, runtool_args)| { + p.arg("--target").arg(&compilation.target); + p.arg("--runtool").arg(runtool); + for arg in runtool_args { + p.arg("--runtool-arg").arg(arg); + } + }); + for &rust_dep in &[&compilation.deps_output] { let mut arg = OsString::from("dependency="); arg.push(rust_dep); @@ -194,7 +203,6 @@ fn run_doc_tests( if let Some(flags) = compilation.rustdocflags.get(&package.package_id()) { p.args(flags); } - config .shell() .verbose(|shell| shell.status("Running", p.to_string()))?; diff --git a/tests/testsuite/cross_compile.rs b/tests/testsuite/cross_compile.rs index 671afe7003a..c7121d9a077 100644 --- a/tests/testsuite/cross_compile.rs +++ b/tests/testsuite/cross_compile.rs @@ -535,7 +535,8 @@ fn cross_tests() { [COMPILING] foo v0.0.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/{triple}/debug/deps/foo-[..][EXE] -[RUNNING] target/{triple}/debug/deps/bar-[..][EXE]", +[RUNNING] target/{triple}/debug/deps/bar-[..][EXE] +[DOCTEST] Skipping doctests, no runner defined for target", triple = target )) .with_stdout_contains("test test_foo ... ok") @@ -595,6 +596,7 @@ fn no_cross_doctests() { [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/{triple}/debug/deps/foo-[..][EXE] +[DOCTEST] Skipping doctests, no runner defined for target ", triple = target )) @@ -1223,7 +1225,8 @@ fn cross_test_dylib() { [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/{arch}/debug/deps/foo-[..][EXE] -[RUNNING] target/{arch}/debug/deps/test-[..][EXE]", +[RUNNING] target/{arch}/debug/deps/test-[..][EXE] +[DOCTEST] Skipping doctests, no runner defined for target", arch = cross_compile::alternate() )) .with_stdout_contains_n("test foo ... ok", 2) From a5235b7bbac8bd2dfb1c3f4da897f402ca035e67 Mon Sep 17 00:00:00 2001 From: Dario Gonzalez Date: Tue, 11 Jun 2019 14:37:47 -0700 Subject: [PATCH 2/3] moved cross-compiling doctests behind the doctest-xcompile feature flag --- src/cargo/core/features.rs | 2 ++ src/cargo/ops/cargo_test.rs | 18 ++++++++++++++---- tests/testsuite/cross_compile.rs | 7 ++----- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index 0e0ffb3fe6f..dd24951bbd1 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -336,6 +336,7 @@ pub struct CliUnstable { pub binary_dep_depinfo: bool, pub build_std: Option>, pub timings: Option>, + pub doctest_xcompile: bool, } impl CliUnstable { @@ -393,6 +394,7 @@ impl CliUnstable { self.build_std = Some(crate::core::compiler::standard_lib::parse_unstable_flag(v)) } "timings" => self.timings = Some(parse_timings(v)), + "doctest-xcompile" => self.doctest_xcompile = true, _ => failure::bail!("unknown `-Z` flag specified: {}", k), } diff --git a/src/cargo/ops/cargo_test.rs b/src/cargo/ops/cargo_test.rs index 0bb3a65c687..23bbe1e8a50 100644 --- a/src/cargo/ops/cargo_test.rs +++ b/src/cargo/ops/cargo_test.rs @@ -140,7 +140,16 @@ fn run_doc_tests( let mut errors = Vec::new(); let config = options.compile_opts.config; - let runtool = compilation.target_runner(); + // The unstable doctest-xcompile feature enables both per-target-ignores and + // cross-compiling doctests. As a side effect, this feature also gates running + // doctests with runtools when target == host. + let doctest_xcompile = config.cli_unstable().doctest_xcompile; + let mut runtool: &Option<(std::path::PathBuf, Vec)> = &None; + if doctest_xcompile { + runtool = compilation.target_runner(); + } else if compilation.host != compilation.target { + return Ok((Test::Doc, errors)); + } for doctest_info in &compilation.to_doc_test { let Doctest { @@ -155,9 +164,10 @@ fn run_doc_tests( .arg("--crate-name") .arg(&target.crate_name()); - p.arg("-Z"); - p.arg("unstable-options"); - p.arg("--enable-per-target-ignores"); + if doctest_xcompile { + p.arg("-Zunstable-options"); + p.arg("--enable-per-target-ignores"); + } runtool.as_ref().map(|(runtool, runtool_args)| { p.arg("--target").arg(&compilation.target); diff --git a/tests/testsuite/cross_compile.rs b/tests/testsuite/cross_compile.rs index c7121d9a077..671afe7003a 100644 --- a/tests/testsuite/cross_compile.rs +++ b/tests/testsuite/cross_compile.rs @@ -535,8 +535,7 @@ fn cross_tests() { [COMPILING] foo v0.0.0 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/{triple}/debug/deps/foo-[..][EXE] -[RUNNING] target/{triple}/debug/deps/bar-[..][EXE] -[DOCTEST] Skipping doctests, no runner defined for target", +[RUNNING] target/{triple}/debug/deps/bar-[..][EXE]", triple = target )) .with_stdout_contains("test test_foo ... ok") @@ -596,7 +595,6 @@ fn no_cross_doctests() { [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/{triple}/debug/deps/foo-[..][EXE] -[DOCTEST] Skipping doctests, no runner defined for target ", triple = target )) @@ -1225,8 +1223,7 @@ fn cross_test_dylib() { [COMPILING] foo v0.0.1 ([CWD]) [FINISHED] dev [unoptimized + debuginfo] target(s) in [..] [RUNNING] target/{arch}/debug/deps/foo-[..][EXE] -[RUNNING] target/{arch}/debug/deps/test-[..][EXE] -[DOCTEST] Skipping doctests, no runner defined for target", +[RUNNING] target/{arch}/debug/deps/test-[..][EXE]", arch = cross_compile::alternate() )) .with_stdout_contains_n("test foo ... ok", 2) From a2209fc590e9d27e51631b049fe53147cf2690a6 Mon Sep 17 00:00:00 2001 From: Dario Gonzalez Date: Thu, 12 Sep 2019 11:08:29 -0700 Subject: [PATCH 3/3] added tests --- src/cargo/ops/cargo_test.rs | 2 +- tests/testsuite/test.rs | 230 ++++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+), 1 deletion(-) diff --git a/src/cargo/ops/cargo_test.rs b/src/cargo/ops/cargo_test.rs index 23bbe1e8a50..f49821cdfef 100644 --- a/src/cargo/ops/cargo_test.rs +++ b/src/cargo/ops/cargo_test.rs @@ -165,12 +165,12 @@ fn run_doc_tests( .arg(&target.crate_name()); if doctest_xcompile { + p.arg("--target").arg(&compilation.target); p.arg("-Zunstable-options"); p.arg("--enable-per-target-ignores"); } runtool.as_ref().map(|(runtool, runtool_args)| { - p.arg("--target").arg(&compilation.target); p.arg("--runtool").arg(runtool); for arg in runtool_args { p.arg("--runtool-arg").arg(arg); diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs index c61924577b7..16539b86115 100644 --- a/tests/testsuite/test.rs +++ b/tests/testsuite/test.rs @@ -8,6 +8,7 @@ use cargo_test_support::registry::Package; use cargo_test_support::{ basic_bin_manifest, basic_lib_manifest, basic_manifest, cargo_exe, project, }; +use cargo_test_support::{cross_compile, is_nightly, paths}; use cargo_test_support::{rustc_host, sleep_ms}; #[cargo_test] @@ -3660,3 +3661,232 @@ fn test_dep_with_dev() { ) .run(); } + +#[cargo_test] +fn cargo_test_doctest_xcompile_ignores() { + if !is_nightly() { + return; + } + let p = project() + .file("Cargo.toml", &basic_lib_manifest("foo")) + .file( + "src/lib.rs", + r#" + ///```ignore-x86_64 + ///assert!(cfg!(not(target_arch = "x86_64"))); + ///``` + pub fn foo() -> u8 { + 4 + } + "#, + ) + .build(); + + p.cargo("build").run(); + #[cfg(not(target_arch = "x86_64"))] + p.cargo("test") + .with_stdout_contains( + "\ + test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out\ + ", + ) + .run(); + #[cfg(target_arch = "x86_64")] + p.cargo("test") + .with_status(101) + .with_stdout_contains( + "\ + test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out\ + ", + ) + .run(); + + #[cfg(not(target_arch = "x86_64"))] + p.cargo("test -Zdoctest-xcompile") + .masquerade_as_nightly_cargo() + .with_stdout_contains( + "\ + test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out\ + ", + ) + .run(); + + #[cfg(target_arch = "x86_64")] + p.cargo("test -Zdoctest-xcompile") + .masquerade_as_nightly_cargo() + .with_stdout_contains( + "\ + test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out\ + ", + ) + .run(); +} + +#[cargo_test] +fn cargo_test_doctest_xcompile() { + if !is_nightly() { + return; + } + let p = project() + .file("Cargo.toml", &basic_lib_manifest("foo")) + .file( + "src/lib.rs", + r#" + + ///``` + ///assert!(1 == 1); + ///``` + pub fn foo() -> u8 { + 4 + } + "#, + ) + .build(); + + p.cargo("build").run(); + p.cargo(&format!("test --target {}", cross_compile::alternate())) + .with_stdout_contains( + "\ + running 0 tests\ + ", + ) + .run(); + p.cargo(&format!( + "test --target {} -Zdoctest-xcompile", + cross_compile::alternate() + )) + .masquerade_as_nightly_cargo() + .with_stdout_contains( + "\ + test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out\ + ", + ) + .run(); +} + +#[cargo_test] +fn cargo_test_doctest_xcompile_runner() { + use std::fs; + if !is_nightly() { + return; + } + + let runner = project() + .file("Cargo.toml", &basic_bin_manifest("runner")) + .file( + "src/main.rs", + r#" + pub fn main() { + eprintln!("this is a runner"); + let args: Vec = std::env::args().collect(); + std::process::Command::new(&args[1]).spawn(); + } + "#, + ) + .build(); + + runner.cargo("build").run(); + assert!(runner.bin("runner").is_file()); + let runner_path = paths::root().join("runner"); + fs::copy(&runner.bin("runner"), &runner_path).unwrap(); + + let config = paths::root().join(".cargo/config"); + + fs::create_dir_all(config.parent().unwrap()).unwrap(); + File::create(config) + .unwrap() + .write_all( + format!( + r#" +[target.'cfg(target_arch = "x86")'] +runner = "{}" +"#, + runner_path.to_str().unwrap() + ) + .as_bytes(), + ) + .unwrap(); + + let p = project() + .file("Cargo.toml", &basic_lib_manifest("foo")) + .file( + "src/lib.rs", + r#" + ///``` + ///assert!(cfg!(target_arch = "x86")); + ///``` + pub fn foo() -> u8 { + 4 + } + "#, + ) + .build(); + + p.cargo("build").run(); + p.cargo(&format!("test --target {}", cross_compile::alternate())) + .with_stdout_contains( + "\ + running 0 tests\ + ", + ) + .run(); + p.cargo(&format!( + "test --target {} -Zdoctest-xcompile", + cross_compile::alternate() + )) + .masquerade_as_nightly_cargo() + .with_stdout_contains( + "\ + test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out\ + ", + ) + .with_stderr_contains( + "\ + this is a runner\ + ", + ) + .run(); +} + +#[cargo_test] +fn cargo_test_doctest_xcompile_no_runner() { + if !is_nightly() { + return; + } + + let p = project() + .file("Cargo.toml", &basic_lib_manifest("foo")) + .file( + "src/lib.rs", + r#" + + ///``` + ///assert!(cfg!(target_arch = "x86")); + ///``` + pub fn foo() -> u8 { + 4 + } + "#, + ) + .build(); + + p.cargo("build").run(); + p.cargo(&format!("test --target {}", cross_compile::alternate())) + .with_stdout_contains( + "\ + running 0 tests\ + ", + ) + .run(); + p.cargo(&format!( + "test --target {} -Zdoctest-xcompile", + cross_compile::alternate() + )) + .masquerade_as_nightly_cargo() + .with_stdout_contains( + "\ + test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out\ + ", + ) + .run(); +}