-
Notifications
You must be signed in to change notification settings - Fork 4.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
Build 5.0.0-pre.20211011.2 fails with "file is generated by these conflicting actions" #14294
Comments
Note: 5.0.0rc2 is failing as well. With 4.2.1 it works fine |
ebac27e is the culprit. |
This should be a release blocker for 5.0, right? Any fix available? |
Ping @sdtwigg |
This class of failure is known and the current plan is to rollforward with it (since the underlying reason is a cc_test being a dependency of a non-test rule is both rare and odd). There are a handful of mitigations (in order that I suggest you try them):
|
@sdtwigg Thanks! Then this is a breaking change instead of a regression, I'll remove it from release blockers. |
Feel free to close this issue if all agree this is not a bug to fix. |
Please consider not closing this issue, but fixing this regression. For us this is neither rare nor odd, but rather affects all our cc_test. Let me give you some background why a dependency of a non-test rule is really important for us and why we assume that also other teams are affected by this: Bazel currently does not support proper .dSYM file creation and has an open issue with this regards: #6327 Our current workaround (which is completely hermetic) to properly debug cc_binary and cc_tests in Bazel on Mac is to have an additional .dSYM target for each of our cc_* executable targets. Therefore, we believe that this is an actual bug that should be fixed and also should not be dismissed as an "odd" use case. |
@rbinnatableau How about using 2. and 3. as temporary workarounds until #6327 is properly fixed? |
Thanks for pointing this out, we tested 2 and 3 seem to be useful workarounds (however having to use an experimental flag feels somehow unsatisfying). Just out of curiosity, could it be a fix to the problem that the test-related options are not taken into considerations for the non test targets and hence such dependencies be allowed again? |
|
Note that
I don't quite follow this question. Can you clarify? More broadly, I appreciate the concerns you're expressing. But this isn't a case of a bug. It's a more challenging case of contradictory user needs.
Your use case is one of the rare ones where this optimization isn't safe. If we roll back the change, then we'll improve your use case but at the expense of the above. We ultimately have to balance these conflicting needs to find the right, most broadly helpful default. Sometimes people have non-tests depending on tests for no important reason. In those cases they should simply refactor their builds. In yours, where you state a conceptual foundation for this structure, it makes sense to discuss your options and how the workaround can help. But we want to try as hard as we can not to hold the I don't believe we have any intention of outright removing Just my comments: @sdtwigg remains the source for definitive guidance. |
@gregestren thank you for explaining the background. This is really helpful. I can totally understand that you don't want to sacrifice the improvements that impact a large number of users. My concern here is that it is not a rare case. In the meantime we have identified two more use cases in our code base that is affected by
In addition, we assume that also all other kind of static analysis, linting tools and packaging targets that depend on test targets are affected by this. If I understand you correctly the proposed solution on your side is to do the following for every non test dependency:
Imho this lead to a scenario where code bases that implemented one of the following use cases are affected:
In such code bases in the worst case all *_test targets will be replaced by *_binary targets + additional sh_test like targets. As this workaround results in a lot of boiler plate code and indirections, I am wondering if there can be another solution that achieves both:
I gather from your previous comment that the way the test flags relate to caching is the reason for the performance improvements achieved by As far as I understand the test flags consist of two parts:
My intuition is that the test specific flags only impact the actual execution of the tests, if it is executed by the test harness and not if they are executed by a Therefore, I don't understand why test flags invalidate subsequent targets, if they do do not depend on the test execution by the test harness (I am quite sure I must be missing something obvious here). |
Seems related to #14236 @diegohavenstein @rbinnatableau |
I have to go a little into Bazel internals to explain why this doesn't quite work. The test flags are currently under the subset of Bazel build options that are part of the build configuration that is passed along to all rules in the build graph (and potentially transitioned e.g. when cfg=exec is used to get targets built for a specific execution platform). The reason why test flags are there is that the test actions are actually being injected as part of that specific rule's implementation during analysis (essentially, right after the main implementation is run, Starlark-defined or otherwise). There isn't really a way to only partially re-run a specific rule's implementation and instead the rule's entire implementation has to be re-run when the build configuration attached to it changes. As a first aside, it was at one point explored to completely remove the test flags from the build configuration and have the top-level re-build test actions as-needed. There are no known hard technical blockers here that would have made this impossible except that this was requiring a bit too much rewriting of top-level code to allow this assumption. (Essentially, far too many disparate places, particularly build event streaming, in top-level were relying on a rule's action always being contained in rule analysis that this approach was not tenable at the time it applied.) As a second aside, the build configuration attached to a rule also needs to also include all the configuration needed by transitive dependencies, even if the current rule doesn't need it. Interestingly, this is not why a non-test rule depending on a test rule is a problem. The test rule is already coded to 'skip' preparing a test action if the test options are missing (as it is assumed in this case the test rule is being analyzed inside the graph, not at top-level, and thus the test action is useless). The action conflict problem occurs when that test rule is analyzed both at the top-level with test options attached and inside the graph without test options attached. In that case two actions are created trying to build the same output file and, this is bad for cc actions which are assumed to be unsharable (excluding the very new
How problematic is the experimental part of the flag? I am highly confident that using it for your cases is the best call here. Part of the reason why the flag is marked as experimental (and kind of in limbo) is that it is not immediately obvious what the best default value for the flag is. The tradeoff is better incrementality performance for all non-test targets (if flag is false else all non-testonly targets) versus correctness in avoiding potential action conflicts for the somewhat rare case users have unsharable test targets (usually cc_test) depended on by non-test targets. Due to the particularities of this flag, it would ideally only be used by users that truly need it. We could set this flag to true by default and have the experimental part be setting it to false (i.e. try to get better performance at risk of correctness). There is a (hopefully minor caveat) that the flag can still cause correctness issue due to an internal Blaze bug as mentioned above; however, those are actually unintentional bugs to be fixed and not intentional breaking changes. |
Summary: For more context about what this diff is doing and why, see D844526. But in short, this diff modifies any BUILD/BUILD.in file that appears to be using `//build_tools:pass` as an exe so it instead uses `//build_tools:pass_binary`. Any other uses of the former were left untouched. My hope is that doing this will let us side-step the issue we discovered in bazelbuild/bazel#14294 -- apparently, in Bazel 5.0, the default value of some flag was changed so that tests cannot be built as dependencies of non-test rules: bazelbuild/bazel@ebac27ec5a6063556 While I don't really understand how our Dropbox-specific bazel stuff works, I'm guessing using `//build_tools:pass` (a test target) as an exe is probably not kosher now due to the above. This hypothesis does have one glaring hole: why is it fine to use `//build_tools/services:restart_test` as the test binary in build_tools/services/svc.bzl, but not `//build_tools:pass`? Both of them are test targets, so you would think that `restart_test` would also be breaking here. There are only three differences between these two targets: - `:restart_test` is located in the same dir as `svc.bzl` - `:restart_test` is a `dbx_sh_test` instead of a `sh_test` - `:restart_test` has the "manual" tag It's possible one of the above differences is responsible for making `:restart_test` work? But this works, so whatever. SEV: https://jira.dropboxer.net/browse/REL-8343 Test Plan: I arc-tested this against server-selective-kubernetes, and confirmed that all test failures related to this went green. GitOrigin-RevId: 510d1384be4f9caf8d94bc03e249dc8144c282e5
I am getting this error trying
Remove the filegroup and the error goes away.
|
This is expected because filegroup is also a non-test rule. Edit: What are you actually trying to do? Because just putting cc_test rules in a filegroup is a tad peculiar. Note that test_suite can be used to group tests together for execution all at once under an alias. Needing filegroup would be more about pulling out the actual underlying test binaries (which exist and can be done but doing so is definitely more advanced behavior than usual). Often, the non-test can be replaced by a proper, custom test rule that does something with those binaries. |
Just though I'd give an example showing how easy it is to hit this issue, especially with a non-executable (iirc) target in the graph. I am slightly curious that |
Reviewing my older notes on this, there are a few experimental flags that may help here:
That said, having tests under non-test rules is very abnormal and can usually be replaced by using test_suite, or in the more advanced cases (e.g. where you want to run the test binary as a subpart of a different test) having the test rules directly under another test rule (e.g. in the original example, set |
Yes your earlier post was helpful.
Is
That sounds convenient enough to use anywhere and without restrictions. Perhaps a note about this issue can be added to the docs? |
I was referring to the dummy rule in the original post (#14294 (comment)). Sorry for the confusion. |
One use-case is a single bazel target producing a summarized code quality report for a larger codebase without the need to collect lots of files and run scripts outside the build tree. That said, it's not necessarily the test results from "bazel test" or "bazel coverage" that is needed. It's easy to depend on test results with Bazel today using a script or a tool that runs the test and saves the result. |
Is there a flag we can enable to make the build fail if a target depends on a test target with a helpful error message so users aren't confused when they see this message? |
This appears to be resolved in Bazel 6 (tested on 6.2.0). At least for the Java tests I attempted to reproduce the issue with. 🤔 This issue only mentions the problem in the context of CC though... Quite possible a change to specific to Java rules resolved the issue there, but worth retesting with the repro steps for CC on Bazel 6.2.0 to be sure. |
Description of the problem / feature request:
When using 5.0.0-pre.20211011.2, calling a rule with testonly=True fails with the following error (see repro):
Feature requests: what underlying problem are you trying to solve with this feature?
Trying out new Bazel version on existing, large codebase
Bugs: what's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.
In an empty dir, create empty WORKSPACE file, and the following files:
What operating system are you running Bazel on?
MacOS BigSur
What's the output of
bazel info release
?release 5.0.0-pre.20211011.2
If
bazel info release
returns "development version" or "(@non-git)", tell us how you built Bazel.Downloaded from Releases page
What's the output of
git remote get-url origin ; git rev-parse master ; git rev-parse HEAD
?Does not apply
Have you found anything relevant by searching the web?
No, found no similar issues reported
Any other information, logs, or outputs that you want to share?
You can reach out to me directly on Slack if I can help out with the repro
The text was updated successfully, but these errors were encountered: