-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Detect cyclic auxiliary #134180
Detect cyclic auxiliary #134180
Conversation
Adds a cycle detection for auxiliary. The function builds a graph from files in the given auxiliary dir, then search the graph using Depth-first search algorithm. The function runs in collect tests time, so a cycle is detected before actual tests are executed. Signed-off-by: Shunpoco <tkngsnsk313320@gmail.com>
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Kobzol (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
|
I'm not sure if we can put a test for compiletest which fails in preparation time, but I ran a manual test on my local:
//@ aux-build:cycle1.rs
//@ should-fail
extern crate cycle1;
//@aux-build:cycle2.rs
extern crate cycle2;
//@aux-build:cycle1.rs
extern crate cycle1; So there is a cycle between cycle1.rs and cycle2.rs.
$ ./x test ./tests/ui/compiletest-self-test/
...
Testing stage1 compiletest suite=ui mode=ui (aarch64-apple-darwin)
thread 'main' panicked at src/tools/compiletest/src/lib.rs:604:13:
Could not read tests from /rust/tests/ui: detect cyclic auxiliary: ["cycle1.rs", "cycle2.rs"]
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Build completed unsuccessfully in 0:00:02 |
Some changes occurred in src/tools/compiletest cc @jieyouxu |
Thanks for the PR. I'll try to do some manual testing tmrw. |
I'm busy this weekend as I'm going to the CS major, I'll revisit this next Monday. Remark (for myself mostly): I took a cursory glance, and the filesystem ops looks potentially expensive, will take a closer look. |
fn build_graph( | ||
config: &Config, | ||
dir: &Path, | ||
base_dir: &Path, | ||
filenames: &mut Vec<String>, | ||
auxiliaries: &mut HashMap<String, Vec<String>>, | ||
) -> io::Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Problem: so I thought about this a bit. build_graph
during test collection that does directory traversal and file reading and prop parsing is quite expensive (especially on slower filesystems like native Windows), and I don't think this is necessarily the right place to do the check.
I would've expected that compiletest does something like:
- First, it collects the tests based on the path filter (or was it test name filter) that was passed from bootstrap.
- Then, compiletest will do some "early props" collection and handling. At this point is when I believe compiletest establishes the basic test conditions and relationships between main test files and their auxiliaries (i.e. if a test will be run or ignored, if it has auxiliaries and such).
- Then, compiletest will further collect and handle "late props".
I would've expected that aux cycle detection happens after early prop collection after we establish the relationship between test files and auxiliaries, and not during test discovery and collection.
Alternatively, we could also just declare that we're not going to handle cyclic auxiliaries and "just don't do that", and doing cyclic auxiliaries is considered PEBKAC as "compiletest did exactly what the user instructed it to do".
cc @oli-obk: how does ui_test
handle infinitely-recursive auxiliaries?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't: oli-obk/ui_test#123
But it should be fixable now that I have a build manager that handles all of these in one place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jieyouxu
Thanks for your review.
- Then, compiletest will do some "early props" collection and handling. At this point is when I believe compiletest establishes the basic test conditions and relationships between main test files and their auxiliaries (i.e. if a test will be run or ignored, if it has auxiliaries and such).
Now I understood that cycle detection should be run around here, is that right?
FYI: EarlyProps gathers auxiliaries only which are referred from the test file. For example from my manual test files above, cycle1.rs
is included in the early_props for aux-cyclic.rs
but cycle2.rs
is not because only cycle1.rs has a dependency to cycle2.rs. So reading files to make a dependency graph is inevitable, but it should be lighter than reading files by entire directory traversal since we can check the cycle only against test files which contains auxs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good question, I'll have to revisit this.
@rustbot review (for revisit) EDIT: I'll revisit this early next week. |
@Shunpoco I thought about this some more, I'd like to postpone adding this detection logic and revisit this during https://rust-lang.github.io/rust-project-goals/2025h1/compiletest-directive-rework.html?highlight=compiletest#making-compiletest-more-maintainable-reworking-directive-handling work, because:
I'm going to close this PR for the time being, thanks for your PR! |
This PR adds a function which detects a cyclic auxiliaries.
It builds a graph from files in the given auxiliary dir, then search if there is a cycle in the graph using DFS.
The function runs when compiletest collects tests from directories, so a cycle is detected before actual tests are executed.
Fixes #133580