Skip to content
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

Have rust_test put its compilation outputs in a subdirectory #1434

Merged
merged 8 commits into from
Jul 7, 2022

Conversation

scentini
Copy link
Collaborator

@scentini scentini commented Jul 5, 2022

This is supposed to fix the long standing Windows flakiness as described in #1427 (comment)

Initially I thought it's an issue with rustdoc_test, however the actual issue is that rust_binary and its rust_test have the same crate name and generate the same intermediary .o files. For sandboxed builds this is not an issue, as the actions are isolated, however, we have a race condition in non-sandboxed builds (Windows):

Let's consider the following build:

bazel build --spawn_strategy=standalone \
    //test/unit/rustdoc:bin_with_transitive_proc_macro \
    //test/unit/rustdoc:bin_with_transitive_proc_macro_test

The bin_with_transitive_proc_macro compile action will create the following intermediate file: bazel-out/k8-fastbuild/bin/test/unit/rustdoc/bin_with_transitive_proc_macro.bin_with_transitive_proc_macro.573369dc-cgu.2.rcgu.o, as will the bin_with_transitive_proc_macro_test action. These two files differ slightly (as the second action is for a test), namely the bin_with_transitive_proc_macro output has the following symbols:

0000000000000000 T main
0000000000000000 t _ZN30bin_with_transitive_proc_macro4main17hfc292cc42314e131E
                 U _ZN3std2rt10lang_start17h1dbc829c47cd61d9E

while the bin_with_transitive_proc_macro_test .o output looks like this:

0000000000000000 T main
0000000000000000 t _ZN30bin_with_transitive_proc_macro4main17h28726504dc060f8dE
                 U _ZN3std2rt10lang_start17h1dbc829c47cd61d9E
                 U _ZN4test16test_main_static17h37e3d88407f5b40fE

Now, when the two actions run in parallel, it can happen that bin_with_transitive_proc_macro creates the output, and bin_with_transitive_proc_macro_test overwrites it. Then, at linking time for bin_with_transitive_proc_macro, rustc will complain:

note: ld.lld: error: undefined symbol: test::test_main_static::h37e3d88407f5b40f

This is because bin_with_transitive_proc_macro is not a test and as such is not linked against libtest.

This PR fixes the issue by directing the compilation outputs of rust_test to be under a test-{hash} directory.

@scentini scentini mentioned this pull request Jul 5, 2022
@scentini scentini requested a review from UebelAndre July 5, 2022 19:45
@scentini
Copy link
Collaborator Author

scentini commented Jul 5, 2022

I believe the current CI failure: LINK : fatal error LNK1181: cannot open input file 'bazel-out\x64_windows-fastbuild\bin\test\rust_test_suite\test-457772782\integrated_tests_suite_tests\patterns\integrated_tests_suite_tests_patterns_fibonacci_test.integrated_tests_suite_tests_patterns_fibonacci_test.db3c722b-cgu.0.rcgu.o' is due to the file having too long a path for Windows
C:/b/hrpx6kwe/execroot/rules_rust/bazel-out\x64_windows-fastbuild\bin\test\rust_test_suite\test-457772782\integrated_tests_suite_tests\patterns\integrated_tests_suite_tests_patterns_fibonacci_test.integrated_tests_suite_tests_patterns_fibonacci_test.db3c722b-cgu.0.rcgu.o <- 271 character.

I shortened it with the last commit, but CI seems slow today, so I'm marking the PR ready for review now.

@scentini scentini marked this pull request as ready for review July 5, 2022 19:48
Copy link
Collaborator

@UebelAndre UebelAndre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Looks good to me, great work!

@@ -384,20 +384,20 @@ def _rust_binary_impl(ctx):
),
)

def _rust_test_common(ctx, toolchain, output):
def _rust_test_common(ctx):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Did this need to change? If _rust_test_impl is just gonna call _rust_test_common, a function that's only parameter is ctx then why the layer of abstraction?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this PR, the output file was declared in _rust_test_impl. As per the changes, it now has a test_{hash} subdirectory, and in order to obtain the hash we need to have the crate root (or the symlink to it in case we had to create such a symlink in order to support generated files). So I would either have to move a lot of the logic from _rust_test_common to _rust_test_impl in order to be able to create the output filename, or to move the declaration of the output file into _rust_test_common. I went with the second option, but I agree that the layer of abstraction is not necessary anymore, and as such I removed _rust_test_common altogether now.
The reason why I put the test outputs into a test_{hash} directory instead of just test or something similar is to avoid conflicts with source directories.

I'll go ahead and merge this PR as you've marked this comment as a nit, but feel free to continue the discussion.

@scentini scentini enabled auto-merge (squash) July 7, 2022 09:42
@scentini scentini closed this Jul 7, 2022
auto-merge was automatically disabled July 7, 2022 09:54

Pull request was closed

@scentini scentini reopened this Jul 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants