Override compile-time test environment paths for relocated test execution#16816
Draft
elyouG wants to merge 3 commits intorust-lang:masterfrom
Draft
Override compile-time test environment paths for relocated test execution#16816elyouG wants to merge 3 commits intorust-lang:masterfrom
elyouG wants to merge 3 commits intorust-lang:masterfrom
Conversation
Some Rust tests embed OUT_DIR-derived paths at compile time, for example
through env!("OUT_DIR") or code generated from it.
That works while tests run from Cargo's original build tree, but it can
break when test binaries are packaged and executed later from a different
installed location. In that situation, the original build-time OUT_DIR
may no longer exist or may point to paths that should not be embedded in
the installed test binary.
Cargo already constructs the compile-time environment for test and bench
units in artifact.rs::get_env(). Add an opt-in override for OUT_DIR so
downstream packaged test environments can redirect it to a valid runtime
location when needed.
The override is only used for test and bench targets, and only when
__CARGO_TEST_OUT_DIR_OVERRIDE is present in Cargo's environment.
Cargo's default behavior remains unchanged otherwise.
Signed-off-by: El Mehdi YOUNES <elmehdi.younes@smile.fr>
Some Rust tests capture CARGO_MANIFEST_DIR at compile time in order to locate fixtures, test inputs, or other resources relative to the package root. That works while tests execute from Cargo's original workspace layout, but it can break when test binaries are packaged and later executed from a different installed location. In those environments, the original build-time manifest directory may no longer exist or may no longer be the right base directory for installed test data. Cargo already constructs the compile-time environment for test and bench units in artifact.rs::get_env(). Add an opt-in override for CARGO_MANIFEST_DIR so downstream packaged test environments can redirect it to an installed test root when needed. The override is only used for test and bench targets, and only when __CARGO_TEST_MANIFEST_DIR_OVERRIDE is present in Cargo's environment. Cargo's default behavior remains unchanged otherwise. Signed-off-by: El Mehdi YOUNES <elmehdi.younes@smile.fr>
Some Rust integration tests launch the program under test through
compile-time variables such as env!("CARGO_BIN_EXE_<name>").
Cargo already synthesizes CARGO_BIN_EXE_* for test and bench units in
artifact.rs::get_env(), normally pointing at a binary location derived
from the build tree. That works while tests execute within Cargo's build
layout, but it can break when test binaries are packaged and later run
from a different installed environment, where the correct program path
may instead be something like an installed bindir location.
Add an opt-in override that lets downstream packaged test environments
redirect the directory used to construct CARGO_BIN_EXE_* values.
When __CARGO_TEST_BIN_EXE_DIR_OVERRIDE is set, Cargo builds
CARGO_BIN_EXE_<name> from that directory and the binary filename.
Otherwise, Cargo keeps its existing behavior unchanged, including the
placeholder fallback for cargo check.
Signed-off-by: El Mehdi YOUNES <elmehdi.younes@smile.fr>
Collaborator
|
r? @epage rustbot has assigned @epage. Use Why was this reviewer chosen?The reviewer was selected based on:
|
Contributor
|
Note that our contrib guide says that PRs should first start as issues that get Accepted by the team before posting PRs. I have a personal write up going into more detail on this at https://epage.github.io/dev/pr-style/#d-issue. |
Author
|
Thanks for the pointer. I've converted this PR back to draft and opened issue #16817 first to discuss the problem and the proposed direction before requesting review again. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR try to resolve?
Cargo already synthesizes several compile-time environment variables for test and bench units in artifact.rs::get_env(), including OUT_DIR, CARGO_MANIFEST_DIR, and CARGO_BIN_EXE_*.
This PR adds optional environment-based overrides for those values when compiling test and bench targets:
The motivation comes from a downstream packaged-test use case, in particular Rust tests executed through Yocto ptest.
In that setup, test binaries are often:
In a regular Cargo workflow, compile-time paths such as OUT_DIR, CARGO_MANIFEST_DIR, and CARGO_BIN_EXE_* usually remain valid because tests execute within Cargo’s own build tree. In packaged test environments, this assumption does not always hold:
As a result, tests that embed these values at compile time can fail even though the tested code itself is correct.
This is not just theoretical. In downstream work, I ran into repeated failures of packaged Rust tests for exactly these reasons. In at least one case (rpm-sequoia), the practical workaround was to add project-specific logic to compensate for invalid runtime paths. The purpose of this PR is to avoid having to solve that class of problem crate-by-crate, and instead provide a small opt-in mechanism directly in Cargo, at the point where Cargo already synthesizes these values.
see rpm-software-management/rpm-sequoia#86
artifact.rs::get_env() is already the place where Cargo constructs these compile-time variables for test and bench units, so it is the natural place to add optional overrides for environments that need to relocate tests outside Cargo’s original build tree.
This makes those paths relocatable when the execution context changes, while preserving Cargo’s existing behavior in the normal case.
The new behavior is strictly opt-in:
From a downstream perspective, this helps avoid project-by-project patches whose only purpose is to work around relocated test paths.
For example, instead of modifying a crate’s tests to introduce custom runtime environment variables or alternate path lookup logic, a downstream Yocto recipe can simply set the desired compile-time values directly:
With this kind of setup, the crate can continue using Cargo’s standard variables, and the downstream environment can adapt them when the test execution layout differs from the build layout.
More generally, I think this also makes Cargo’s standard test environment variables more attractive to projects that do not use them yet. If downstream environments can override them when needed, relying on env!("OUT_DIR"), env!("CARGO_MANIFEST_DIR"), and env!("CARGO_BIN_EXE_") becomes easier to support than ad hoc path reconstruction or custom per-project environment variables.
This PR is currently split into 3 commits for readability:
1.override OUT_DIR
2.override CARGO_MANIFEST_DIR
3.override CARGO_BIN_EXE_*
I am happy to squash them if preferred.
How to test and review this PR?
This PR is easiest to review commit-by-commit, since each commit applies the same opt-in pattern to one compile-time test variable.
For each commit, the main review points are:
I tested this in two ways.
First, I verified that Cargo’s normal behavior remains unchanged when no override variables are set:
Second, I verified that the overrides are picked up correctly when the new variables are provided:
I also validated the approach against the downstream use case that motivated this PR: packaged Rust tests in a Yocto ptest workflow, where tests are compiled in one layout and executed later from another installed location. The goal there is to let downstream environments adapt Cargo’s standard compile-time test variables directly, instead of having to ask each affected crate to introduce project-specific workarounds.
Cc: @ycongal-smile