From 3489428921671b274b08ebbabd00128d56ebaa00 Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Wed, 11 Dec 2019 08:26:08 -0800
Subject: [PATCH 1/3] Set an environment variable for tests to find
executables.
---
.../compiler/context/compilation_files.rs | 32 ++++++++++++-
src/cargo/core/compiler/mod.rs | 17 +++++++
.../src/reference/environment-variables.md | 9 ++++
tests/testsuite/test.rs | 47 +++++++++++++++++++
4 files changed, 104 insertions(+), 1 deletion(-)
diff --git a/src/cargo/core/compiler/context/compilation_files.rs b/src/cargo/core/compiler/context/compilation_files.rs
index 1f8286d06ce..ae885d06797 100644
--- a/src/cargo/core/compiler/context/compilation_files.rs
+++ b/src/cargo/core/compiler/context/compilation_files.rs
@@ -10,7 +10,7 @@ use log::info;
use super::{BuildContext, CompileKind, Context, FileFlavor, Layout};
use crate::core::compiler::{CompileMode, CompileTarget, Unit};
-use crate::core::{TargetKind, Workspace};
+use crate::core::{Target, TargetKind, Workspace};
use crate::util::{self, CargoResult};
/// The `Metadata` is a hash used to make unique file names for each unit in a build.
@@ -241,6 +241,36 @@ impl<'a, 'cfg: 'a> CompilationFiles<'a, 'cfg> {
}
}
+ /// Returns the path to the executable binary for the given bin target.
+ ///
+ /// This should only to be used when a `Unit` is not available.
+ pub fn bin_link_for_target(
+ &self,
+ target: &Target,
+ kind: CompileKind,
+ bcx: &BuildContext<'_, '_>,
+ ) -> CargoResult {
+ assert!(target.is_bin());
+ let dest = self.layout(kind).dest();
+ let info = bcx.info(kind);
+ let file_types = info
+ .file_types(
+ "bin",
+ FileFlavor::Normal,
+ &TargetKind::Bin,
+ kind.short_name(bcx),
+ )?
+ .expect("target must support `bin`");
+
+ let file_type = file_types
+ .iter()
+ .filter(|file_type| file_type.flavor == FileFlavor::Normal)
+ .next()
+ .expect("target must support `bin`");
+
+ Ok(dest.join(file_type.filename(target.name())))
+ }
+
/// Returns the filenames that the given unit will generate.
pub(super) fn outputs(
&self,
diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs
index 5052d790d8e..b763f5b317f 100644
--- a/src/cargo/core/compiler/mod.rs
+++ b/src/cargo/core/compiler/mod.rs
@@ -876,6 +876,23 @@ fn build_base_args<'a, 'cfg>(
cmd.arg("-Zforce-unstable-if-unmarked")
.env("RUSTC_BOOTSTRAP", "1");
}
+
+ // Add `CARGO_BIN_` environment variables for building tests.
+ if unit.target.is_test() || unit.target.is_bench() {
+ for bin_target in unit
+ .pkg
+ .manifest()
+ .targets()
+ .iter()
+ .filter(|target| target.is_bin())
+ {
+ let exe_path = cx
+ .files()
+ .bin_link_for_target(bin_target, unit.kind, cx.bcx)?;
+ let key = format!("CARGO_BIN_EXE_{}", bin_target.crate_name().to_uppercase());
+ cmd.env(&key, exe_path);
+ }
+ }
Ok(())
}
diff --git a/src/doc/src/reference/environment-variables.md b/src/doc/src/reference/environment-variables.md
index 44b018b858c..c99f708e236 100644
--- a/src/doc/src/reference/environment-variables.md
+++ b/src/doc/src/reference/environment-variables.md
@@ -187,6 +187,15 @@ let version = env!("CARGO_PKG_VERSION");
* `OUT_DIR` — If the package has a build script, this is set to the folder where the build
script should place its output. See below for more information.
(Only set during compilation.)
+* `CARGO_BIN_EXE_` — The absolute path to a binary target's executable.
+ This is only set when building an [integration test] or benchmark. This may
+ be used with the [`env` macro] to find the executable to run for testing
+ purposes. The `` is the name of the binary converted to uppercase, and
+ `-` converted to `_`. Binaries are automatically built when the test is
+ built, unless the binary has required features that are not enabled.
+
+[integration test]: manifest.md#integration-tests
+[`env` macro]: ../../std/macro.env.html
#### Dynamic library paths
diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs
index a092002fcc8..c685b51ce8c 100644
--- a/tests/testsuite/test.rs
+++ b/tests/testsuite/test.rs
@@ -3995,3 +3995,50 @@ fn panic_abort_test_profile_inherits() {
.with_status(0)
.run();
}
+
+#[cargo_test]
+fn bin_env_for_test() {
+ // Test for the `CARGO_BIN_` environment variables for tests.
+ //
+ // Note: The Unicode binary uses a `[[bin]]` definition because different
+ // filesystems normalize utf-8 in different ways. For example, HFS uses
+ // "gru\u{308}ßen" and APFS uses "gr\u{fc}ßen". Defining it in TOML forces
+ // one form to be used.
+ let p = project()
+ .file(
+ "Cargo.toml",
+ r#"
+ [package]
+ name = "foo"
+ version = "0.1.0"
+ edition = "2018"
+
+ [[bin]]
+ name = 'grüßen'
+ path = 'src/bin/grussen.rs'
+ "#,
+ )
+ .file("src/bin/foo.rs", "fn main() {}")
+ .file("src/bin/with-dash.rs", "fn main() {}")
+ .file("src/bin/grussen.rs", "fn main() {}")
+ .build();
+
+ let bin_path = |name| p.bin(name).to_string_lossy().replace("\\", "\\\\");
+ p.change_file(
+ "tests/check_env.rs",
+ &r#"
+ #[test]
+ fn run_bins() {
+ assert_eq!(env!("CARGO_BIN_EXE_FOO"), "");
+ assert_eq!(env!("CARGO_BIN_EXE_WITH_DASH"), "");
+ assert_eq!(env!("CARGO_BIN_EXE_GRÜSSEN"), "");
+ }
+ "#
+ .replace("", &bin_path("foo"))
+ .replace("", &bin_path("with-dash"))
+ .replace("", &bin_path("grüßen")),
+ );
+
+ p.cargo("test --test check_env").run();
+ p.cargo("check --test check_env").run();
+}
From 499f917c03f4a4956b83bb497f247e75311528ee Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Thu, 6 Feb 2020 08:30:09 -0800
Subject: [PATCH 2/3] Switch to case-sensitive environment variable.
---
src/cargo/core/compiler/mod.rs | 2 +-
src/doc/src/reference/environment-variables.md | 7 ++++---
tests/testsuite/test.rs | 6 +++---
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs
index b763f5b317f..1995501b6cc 100644
--- a/src/cargo/core/compiler/mod.rs
+++ b/src/cargo/core/compiler/mod.rs
@@ -889,7 +889,7 @@ fn build_base_args<'a, 'cfg>(
let exe_path = cx
.files()
.bin_link_for_target(bin_target, unit.kind, cx.bcx)?;
- let key = format!("CARGO_BIN_EXE_{}", bin_target.crate_name().to_uppercase());
+ let key = format!("CARGO_BIN_EXE_{}", bin_target.name());
cmd.env(&key, exe_path);
}
}
diff --git a/src/doc/src/reference/environment-variables.md b/src/doc/src/reference/environment-variables.md
index c99f708e236..6ba68c6ae7a 100644
--- a/src/doc/src/reference/environment-variables.md
+++ b/src/doc/src/reference/environment-variables.md
@@ -190,9 +190,10 @@ let version = env!("CARGO_PKG_VERSION");
* `CARGO_BIN_EXE_` — The absolute path to a binary target's executable.
This is only set when building an [integration test] or benchmark. This may
be used with the [`env` macro] to find the executable to run for testing
- purposes. The `` is the name of the binary converted to uppercase, and
- `-` converted to `_`. Binaries are automatically built when the test is
- built, unless the binary has required features that are not enabled.
+ purposes. The `` is the name of the binary target, exactly as-is. For
+ example, `CARGO_BIN_EXE_my-program` for a binary named `my-program`.
+ Binaries are automatically built when the test is built, unless the binary
+ has required features that are not enabled.
[integration test]: manifest.md#integration-tests
[`env` macro]: ../../std/macro.env.html
diff --git a/tests/testsuite/test.rs b/tests/testsuite/test.rs
index c685b51ce8c..9d356bc92fe 100644
--- a/tests/testsuite/test.rs
+++ b/tests/testsuite/test.rs
@@ -4029,9 +4029,9 @@ fn bin_env_for_test() {
&r#"
#[test]
fn run_bins() {
- assert_eq!(env!("CARGO_BIN_EXE_FOO"), "");
- assert_eq!(env!("CARGO_BIN_EXE_WITH_DASH"), "");
- assert_eq!(env!("CARGO_BIN_EXE_GRÜSSEN"), "");
+ assert_eq!(env!("CARGO_BIN_EXE_foo"), "");
+ assert_eq!(env!("CARGO_BIN_EXE_with-dash"), "");
+ assert_eq!(env!("CARGO_BIN_EXE_grüßen"), "");
}
"#
.replace("", &bin_path("foo"))
From 4cf531f5a6939fb92c095dd76e252bf778815b01 Mon Sep 17 00:00:00 2001
From: Eric Huss
Date: Thu, 6 Feb 2020 22:03:59 -0800
Subject: [PATCH 3/3] Add more docs on CARGO_BIN_EXE_.
---
src/doc/man/cargo-test.adoc | 8 ++++++++
src/doc/man/generated/cargo-test.html | 9 +++++++++
src/doc/src/reference/cargo-targets.md | 9 +++++++++
src/doc/src/reference/environment-variables.md | 2 +-
src/etc/man/cargo-test.1 | 14 ++++++++++++--
5 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/src/doc/man/cargo-test.adoc b/src/doc/man/cargo-test.adoc
index a4e6d80ed4c..32aa5ff6688 100644
--- a/src/doc/man/cargo-test.adoc
+++ b/src/doc/man/cargo-test.adoc
@@ -74,6 +74,14 @@ ignore the `test` flag and will always test the given target.
Doc tests for libraries may be disabled by setting `doctest = false` for the
library in the manifest.
+Binary targets are automatically built if there is an integration test or
+benchmark. This allows an integration test to execute the binary to exercise
+and test its behavior. The `CARGO_BIN_EXE_`
+linkcargo:reference/environment-variables.html#environment-variables-cargo-sets-for-crates[environment variable]
+is set when the integration test is built so that it can use the
+link:https://doc.rust-lang.org/std/macro.env.html[`env` macro] to locate the
+executable.
+
include::options-targets.adoc[]
*--doc*::
diff --git a/src/doc/man/generated/cargo-test.html b/src/doc/man/generated/cargo-test.html
index faa7ee72292..bbf162dc88f 100644
--- a/src/doc/man/generated/cargo-test.html
+++ b/src/doc/man/generated/cargo-test.html
@@ -154,6 +154,15 @@ Target Selection
library in the manifest.
+
Binary targets are automatically built if there is an integration test or
+benchmark. This allows an integration test to execute the binary to exercise
+and test its behavior. The CARGO_BIN_EXE_<name>
+environment variable
+is set when the integration test is built so that it can use the
+env
macro to locate the
+executable.
+
+
Passing target selection flags will test only the
specified targets.
diff --git a/src/doc/src/reference/cargo-targets.md b/src/doc/src/reference/cargo-targets.md
index 4be13c3529f..ebff8be475d 100644
--- a/src/doc/src/reference/cargo-targets.md
+++ b/src/doc/src/reference/cargo-targets.md
@@ -123,6 +123,15 @@ modules. The libtest harness will automatically find all of the `#[test]`
annotated functions and run them in parallel. You can pass module names to
[`cargo test`] to only run the tests within that module.
+Binary targets are automatically built if there is an integration test. This
+allows an integration test to execute the binary to exercise and test its
+behavior. The `CARGO_BIN_EXE_` [environment variable] is set when the
+integration test is built so that it can use the [`env` macro] to locate the
+executable.
+
+[environment variable]: environment-variables.md#environment-variables-cargo-sets-for-crates
+[`env` macro]: ../../std/macro.env.html
+
### Benchmarks
Benchmarks provide a way to test the performance of your code using the
diff --git a/src/doc/src/reference/environment-variables.md b/src/doc/src/reference/environment-variables.md
index 6ba68c6ae7a..bfd973a7932 100644
--- a/src/doc/src/reference/environment-variables.md
+++ b/src/doc/src/reference/environment-variables.md
@@ -195,7 +195,7 @@ let version = env!("CARGO_PKG_VERSION");
Binaries are automatically built when the test is built, unless the binary
has required features that are not enabled.
-[integration test]: manifest.md#integration-tests
+[integration test]: cargo-targets.md#integration-tests
[`env` macro]: ../../std/macro.env.html
#### Dynamic library paths
diff --git a/src/etc/man/cargo-test.1 b/src/etc/man/cargo-test.1
index 26a0aebf6bd..4ebb9def95f 100644
--- a/src/etc/man/cargo-test.1
+++ b/src/etc/man/cargo-test.1
@@ -2,12 +2,12 @@
.\" Title: cargo-test
.\" Author: [see the "AUTHOR(S)" section]
.\" Generator: Asciidoctor 2.0.10
-.\" Date: 2020-01-18
+.\" Date: 2020-02-06
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
-.TH "CARGO\-TEST" "1" "2020-01-18" "\ \&" "\ \&"
+.TH "CARGO\-TEST" "1" "2020-02-06" "\ \&" "\ \&"
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.ss \n[.ss] 0
@@ -206,6 +206,16 @@ ignore the \fBtest\fP flag and will always test the given target.
Doc tests for libraries may be disabled by setting \fBdoctest = false\fP for the
library in the manifest.
.sp
+Binary targets are automatically built if there is an integration test or
+benchmark. This allows an integration test to execute the binary to exercise
+and test its behavior. The \fBCARGO_BIN_EXE_\fP
+\c
+.URL "https://doc.rust\-lang.org/cargo/reference/environment\-variables.html#environment\-variables\-cargo\-sets\-for\-crates" "environment variable"
+is set when the integration test is built so that it can use the
+.URL "https://doc.rust\-lang.org/std/macro.env.html" "\fBenv\fP macro" " "
+to locate the
+executable.
+.sp
Passing target selection flags will test only the
specified targets.
.sp