Skip to content

Commit 00c4697

Browse files
yerkeepage
authored andcommitted
add CARGO_WORKSPACE_DIR env var for integration tests and benchmarks
1 parent 0fcc90d commit 00c4697

File tree

3 files changed

+264
-1
lines changed

3 files changed

+264
-1
lines changed

src/cargo/core/compiler/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,22 @@ fn prepare_rustc(cx: &Context<'_, '_>, unit: &Unit) -> CargoResult<ProcessBuilde
670670
if unit.target.is_test() || unit.target.is_bench() {
671671
let tmp = cx.files().layout(unit.kind).prepare_tmp()?;
672672
base.env("CARGO_TARGET_TMPDIR", tmp.display().to_string());
673+
674+
if cx.bcx.config.nightly_features_allowed {
675+
// Use a relative path and limit to integration tests and benchmarks in hopes
676+
// that it conveys to the user that the meaning of this value is a bit fuzzy
677+
// (very different meaning in the original repo vs once published).
678+
let cargo_workspace_dir = if is_primary && is_workspace {
679+
pathdiff::diff_paths(cx.bcx.ws.root(), unit.pkg.root())
680+
.expect("both paths are absolute")
681+
.display()
682+
.to_string()
683+
} else {
684+
// path from unit.pkg.root() to unit.pkg.root()
685+
".".to_string()
686+
};
687+
base.env("CARGO_WORKSPACE_DIR", cargo_workspace_dir);
688+
}
673689
}
674690

675691
base.inherit_jobserver(&cx.jobserver);

src/doc/src/reference/environment-variables.md

+5
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,11 @@ corresponding environment variable is set to the empty string, `""`.
265265
where integration tests or benchmarks are free to put any data needed by
266266
the tests/benches. Cargo initially creates this directory but doesn't
267267
manage its content in any way, this is the responsibility of the test code.
268+
* `CARGO_WORKSPACE_DIR` --- Only set when building [integration test] or benchmark code.
269+
This is a path to the workspace directory of the package being built. When there is
270+
no associated workspace, which includes all registry packages, this will be a path to
271+
the directory that contains the manifest of the package.
272+
Currently, it is implemented as a relative path.
268273

269274
[Cargo target]: cargo-targets.md
270275
[binaries]: cargo-targets.md#binaries

tests/testsuite/build.rs

+243-1
Original file line numberDiff line numberDiff line change
@@ -1477,7 +1477,7 @@ fn cargo_default_env_metadata_env_var() {
14771477
}
14781478

14791479
#[cargo_test]
1480-
fn crate_env_vars() {
1480+
fn crate_env_vars_without_workspace() {
14811481
let p = project()
14821482
.file(
14831483
"Cargo.toml",
@@ -1545,6 +1545,9 @@ fn crate_env_vars() {
15451545
15461546
// Verify CARGO_TARGET_TMPDIR isn't set for bins
15471547
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
1548+
1549+
// Verify CARGO_WORKSPACE_DIR isn't set for bins
1550+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
15481551
}
15491552
"#,
15501553
)
@@ -1588,6 +1591,10 @@ fn crate_env_vars() {
15881591
// Check that CARGO_TARGET_TMPDIR isn't set for unit tests
15891592
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
15901593
env::var("CARGO_TARGET_TMPDIR").unwrap_err();
1594+
1595+
// Check that CARGO_WORKSPACE_DIR isn't set for unit tests
1596+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
1597+
env::var("CARGO_WORKSPACE_DIR").unwrap_err();
15911598
}
15921599
"#,
15931600
)
@@ -1605,6 +1612,9 @@ fn crate_env_vars() {
16051612
16061613
// Verify CARGO_TARGET_TMPDIR isn't set for examples
16071614
assert!(option_env!("CARGO_TARGET_TMPDIR").is_none());
1615+
1616+
// Verify CARGO_WORKSPACE_DIR isn't set for examples
1617+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
16081618
}
16091619
"#,
16101620
)
@@ -1614,6 +1624,9 @@ fn crate_env_vars() {
16141624
#[test]
16151625
fn env() {
16161626
foo::check_tmpdir(option_env!("CARGO_TARGET_TMPDIR"));
1627+
1628+
// Verify CARGO_WORKSPACE_DIR isn't set for integration tests without masquerade_as_nightly_cargo()
1629+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
16171630
}
16181631
"#,
16191632
);
@@ -1629,6 +1642,9 @@ fn crate_env_vars() {
16291642
#[bench]
16301643
fn env(_: &mut Bencher) {
16311644
foo::check_tmpdir(option_env!("CARGO_TARGET_TMPDIR"));
1645+
1646+
// Verify CARGO_WORKSPACE_DIR isn't set for benches without masquerade_as_nightly_cargo()
1647+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
16321648
}
16331649
"#,
16341650
)
@@ -1657,6 +1673,232 @@ fn crate_env_vars() {
16571673
}
16581674
}
16591675

1676+
#[cargo_test]
1677+
fn nightly_cargo_workspace_dir_env_var_with_workspace() {
1678+
Package::new("bar", "0.1.0")
1679+
.file("src/lib.rs", "#[test] fn bar() {}")
1680+
.file(
1681+
"tests/env.rs",
1682+
r#"
1683+
use std::path::Path;
1684+
1685+
#[test]
1686+
fn env() {
1687+
assert!(Path::new(option_env!("CARGO_WORKSPACE_DIR").unwrap()).join(file!()).exists());
1688+
assert_eq!(std::fs::canonicalize(option_env!("CARGO_WORKSPACE_DIR").unwrap()).unwrap().display().to_string(), option_env!("CARGO_MANIFEST_DIR").unwrap());
1689+
}
1690+
"#,
1691+
)
1692+
.publish();
1693+
1694+
let p = project()
1695+
.file(
1696+
"Cargo.toml",
1697+
r#"
1698+
[workspace]
1699+
members = ["foo"]
1700+
"#,
1701+
)
1702+
.file(
1703+
"foo/Cargo.toml",
1704+
r#"
1705+
[package]
1706+
name = "foo"
1707+
version = "0.0.1"
1708+
authors = []
1709+
1710+
[dependencies]
1711+
bar = "0.1.0"
1712+
1713+
[[bin]]
1714+
name = "foo-bar"
1715+
path = "src/main.rs"
1716+
"#,
1717+
)
1718+
.file(
1719+
"foo/src/main.rs",
1720+
r#"
1721+
fn main() {
1722+
// Verify CARGO_WORKSPACE_DIR isn't set for bins
1723+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
1724+
}
1725+
"#,
1726+
)
1727+
.file(
1728+
"foo/src/lib.rs",
1729+
r#"
1730+
use std::env;
1731+
1732+
#[test]
1733+
fn env() {
1734+
// Check that CARGO_WORKSPACE_DIR isn't set for unit tests
1735+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
1736+
env::var("CARGO_WORKSPACE_DIR").unwrap_err();
1737+
}
1738+
"#,
1739+
)
1740+
.file(
1741+
"foo/examples/ex-env-vars.rs",
1742+
r#"
1743+
fn main() {
1744+
// Verify CARGO_WORKSPACE_DIR isn't set for examples
1745+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
1746+
}
1747+
"#,
1748+
)
1749+
.file(
1750+
"foo/tests/env.rs",
1751+
r#"
1752+
use std::path::Path;
1753+
1754+
#[test]
1755+
fn env() {
1756+
assert!(Path::new(option_env!("CARGO_WORKSPACE_DIR").unwrap()).join(file!()).exists());
1757+
}
1758+
"#,
1759+
);
1760+
1761+
let p = if is_nightly() {
1762+
p.file(
1763+
"foo/benches/env.rs",
1764+
r#"
1765+
#![feature(test)]
1766+
extern crate test;
1767+
use std::path::Path;
1768+
use test::Bencher;
1769+
1770+
#[bench]
1771+
fn env(_: &mut Bencher) {
1772+
assert!(Path::new(option_env!("CARGO_WORKSPACE_DIR").unwrap()).join(file!()).exists());
1773+
}
1774+
"#,
1775+
)
1776+
.build()
1777+
} else {
1778+
p.build()
1779+
};
1780+
1781+
println!("build");
1782+
p.cargo("build -v").run();
1783+
1784+
println!("bin");
1785+
p.process(&p.bin("foo-bar")).run();
1786+
1787+
println!("example");
1788+
p.cargo("run --example ex-env-vars -v").run();
1789+
1790+
println!("test");
1791+
p.cargo("test -v").masquerade_as_nightly_cargo(&[]).run();
1792+
1793+
if is_nightly() {
1794+
println!("bench");
1795+
p.cargo("bench -v").masquerade_as_nightly_cargo(&[]).run();
1796+
}
1797+
1798+
p.cargo("test -p bar")
1799+
.masquerade_as_nightly_cargo(&[])
1800+
.with_stdout_contains("running 1 test\ntest bar ... ok")
1801+
.run();
1802+
}
1803+
1804+
#[cargo_test]
1805+
fn nightly_cargo_workspace_dir_env_var_without_workspace() {
1806+
let p = project()
1807+
.file(
1808+
"Cargo.toml",
1809+
r#"
1810+
[package]
1811+
name = "foo"
1812+
version = "0.0.1"
1813+
authors = []
1814+
1815+
[[bin]]
1816+
name = "foo-bar"
1817+
path = "src/main.rs"
1818+
"#,
1819+
)
1820+
.file(
1821+
"src/main.rs",
1822+
r#"
1823+
extern crate foo;
1824+
1825+
fn main() {
1826+
// Verify CARGO_WORKSPACE_DIR isn't set for bins
1827+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
1828+
}
1829+
"#,
1830+
)
1831+
.file(
1832+
"src/lib.rs",
1833+
r#"
1834+
use std::env;
1835+
#[test]
1836+
fn env() {
1837+
// Check that CARGO_WORKSPACE_DIR isn't set for unit tests
1838+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
1839+
env::var("CARGO_WORKSPACE_DIR").unwrap_err();
1840+
}
1841+
"#,
1842+
)
1843+
.file(
1844+
"examples/ex-env-vars.rs",
1845+
r#"
1846+
fn main() {
1847+
// Verify CARGO_WORKSPACE_DIR isn't set for examples
1848+
assert!(option_env!("CARGO_WORKSPACE_DIR").is_none());
1849+
}
1850+
"#,
1851+
)
1852+
.file(
1853+
"tests/env.rs",
1854+
r#"
1855+
use std::path::Path;
1856+
1857+
#[test]
1858+
fn env() {
1859+
assert!(Path::new(option_env!("CARGO_WORKSPACE_DIR").unwrap()).join(file!()).exists());
1860+
}
1861+
"#,
1862+
);
1863+
1864+
let p = if is_nightly() {
1865+
p.file(
1866+
"benches/env.rs",
1867+
r#"
1868+
#![feature(test)]
1869+
extern crate test;
1870+
use std::path::Path;
1871+
use test::Bencher;
1872+
1873+
#[bench]
1874+
fn env(_: &mut Bencher) {
1875+
assert!(Path::new(option_env!("CARGO_WORKSPACE_DIR").unwrap()).join(file!()).exists());
1876+
}
1877+
"#,
1878+
)
1879+
.build()
1880+
} else {
1881+
p.build()
1882+
};
1883+
1884+
println!("build");
1885+
p.cargo("build -v").run();
1886+
1887+
println!("bin");
1888+
p.process(&p.bin("foo-bar")).run();
1889+
1890+
println!("example");
1891+
p.cargo("run --example ex-env-vars -v").run();
1892+
1893+
println!("test");
1894+
p.cargo("test -v").masquerade_as_nightly_cargo(&[]).run();
1895+
1896+
if is_nightly() {
1897+
println!("bench");
1898+
p.cargo("bench -v").masquerade_as_nightly_cargo(&[]).run();
1899+
}
1900+
}
1901+
16601902
#[cargo_test]
16611903
fn crate_authors_env_vars() {
16621904
let p = project()

0 commit comments

Comments
 (0)