-
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
cquery ignores test config in .bazelrc files #13428
Comments
@sdtwigg has input on this. |
@sdtwigg I'd love to hear your thoughts, if you wouldn't mind sharing! |
This is roughly working as expected. The cquery command inherits from the build command so it will only see bazelrc entries with In practice, we generally advise being careful with triggering off |
The specific problem I'm trying to solve is: "Given this patch, what tests will have different results (and thus need running on CI)", and using Is there a nice way to do this? If not, could we perhaps add a
Given that, shouldn't |
Can you define further what it means for a test to be affected by a change? Like...different output? Different config hash? Is your interest specifically in |
I'd give the definition: A test is affected by a change if, running the test after the change, it may have a different result than running it before the change. With the assumption that tests are deterministic, reliable, and self-contained (dealing with things like flakiness or talking on the network is another matter). We'd rather over-estimate than under-estimate (under-estimating leads to broken changes getting merged, which is really bad. Over-estimating leads to wasted resources and potentially extra developer latency, which is bad, but nowhere near as bad). So - different output, definitely. Different config hash - probably a reasonable proxy for different output (but by ignoring config which affects the test runner action, we veer towards under-estimating, which is problematic). Any flag set by the |
Thanks. Even more naively, wouldn't all test targets show a different hash from a changed flag? If the approximation isn't actually running the test to compare the output, what's distinguishing affected vs. non-affected tests? I think there's something more fundamental I'm missing. I know there's |
Yes, if someone adds a
The next step in the pipeline is to run the affected tests. The goal here is to determine what targets need to run for a particular CI run. So the steps are: Determine affected targets -> Run affected tests -> Publish affected releasable artifacts We're looking to avoid running unaffected tests (partially to avoid spending resources where we may get spurious cache misses, partially to avoid running flaky tests, and partially to avoid failing a PR because of known-failing tests elsewhere in the repo). |
Getting back to technical details, I acknowledge there's a weird interaction between For example, this works just fine:
I was hoping |
Yeah, it's a really weird corner - there's presumably special handling somewhere to accept |
I don't think
bazel/src/main/java/com/google/devtools/build/lib/runtime/commands/CqueryCommand.java Line 51 in 09c621e
which gives it access to all build and test flags.
bazel/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java Lines 55 to 62 in 09c621e
and I think only gets the flags explicitly itemized in its definition (
Happy to chat about this as much as you want. It's good to explore reality, but I'm not sure where this takes us toward envisioning a happy resolution. |
Yeah, it would definitely be good to get back towards a solution! How would you feel about something like a new Slightly less helpful but still handy could be a |
For better or worse I'm increasingly inspired by the Lukacs Berki and Alan Donovan school of thought of fearing Bazel's complexity and being ridiculously cautious about expanding it (and of course ideally reducing it). So my major first reactions are to fully explore what's possible today. Expanding on your second slightly less helpful point, could this help?
I experimented a bit and I think it provides enough raw information to reproduce whatever you need: both loaded |
Tone clarification: "slightly less helpful" in that you noted it as such. Not that your feedback is less helpful to me. 😄 |
I like the creativity! I think it has the basis for something helpful, but... A handful of issues:
to a
I guess it's probably relatively easy to fix this by passing the args through a shlex-like library before outputting them? WDYT? |
You mentioned earlier that a All in the last comment makes sense, but I'd still like to explore more what's possible now and exactly how the functionality is used. Expanding yet further the space of possibilities, I also thought about:
|
In general most
I tried this out, and I couldn't come up with a reliable algorithm for parsing this information out. Things I saw:
{
"combinedForm": "--default_override=1:test=--test_arg=beep",
"optionName": "default_override",
"optionValue": "1:test=--test_arg=beep",
"effectTags": [
"CHANGES_INPUTS"
],
"metadataTags": [
"HIDDEN"
]
}, and one specified on the command line: {
"combinedForm": "--test_arg=boop",
"optionName": "test_arg",
"optionValue": "boop",
"effectTags": [
"UNKNOWN"
]
} And this is how two {
"combinedForm": "--default_override=1:test=--test_output=all",
"optionName": "default_override",
"optionValue": "1:test=--test_output=all",
"effectTags": [
"CHANGES_INPUTS"
],
"metadataTags": [
"HIDDEN"
]
}, {
"combinedForm": "--default_override=3:test=--test_output=errors",
"optionName": "default_override",
"optionValue": "3:test=--test_output=errors",
"effectTags": [
"CHANGES_INPUTS"
],
"metadataTags": [
"HIDDEN"
]
}, I can't see an obvious pattern in these outputs which would let me say "the resolved flags here are
"--default_override=1:test=--test_arg=beep",
"--default_override=1:test=--test_output=all",
[...]
"--default_override=3:test=--test_output=errors",
[...]
"--test_output=errors",
"--test_arg=boop" but I don't see a clear, reliable path to transform that into what's actually relevant.
Honestly this would be perfect for me :) |
This makes flags like `--test_arg` present in `.bazelrc` files be factored into the configuration hash for test targets. See bazelbuild#13428 for extensive context.
I filed #13491 - let's see what breaks! :) |
This makes sense! (but I had to do the ad hoc code looking up you describe to verify, which provides your point). Thank you.
Looks like the PR presubmit is clean? Even better would be to teach bazelrc processing to understand In spirit This does shake up the analysis caching concerns @sdtwigg mentioned above - switching between build or test or cquery may re-do analysis depending on what flags |
I'm not sure I completely follow what this would look like - is the idea that you could specify what command |
The relevant implementation logic is bazel/src/main/java/com/google/devtools/build/lib/runtime/BlazeOptionHandler.java Lines 162 to 179 in 329b22a
There's interesting enough commentary in the Javadoc. The criteria for qualifying which bazel/src/main/java/com/google/devtools/build/lib/runtime/BlazeOptionHandler.java Lines 379 to 384 in 329b22a
which basically means "the current command and its inheritance hierarchy". Which is why I was wondering if we could be even more explicit: tell The only other impact of changing the inheritance is whatever overrides in https://github.com/bazelbuild/bazel/blob/f6a822f5f922ff33a3ad97491c26a6a28e4a7692/src/main/java/com/google/devtools/build/lib/runtime/commands/TestCommand.java will also kick in. Since it's cquery, which is spiritually equivalent to One further question: |
Of the existing ones, the only one I imagine believe people wanting to act like is
Thanks for the pointers!
If we can find a nice way to signal it (it can't Just be a flag, because it's needed to drive the flag parsing - maybe it could be a flag which can only be specified on the command line...), being able to drive "This private void getCommandNamesToParseHelper(
Command commandAnnotation, List<String> accumulator) {
Command commandForInheritance = commandAnnotation;
if (commandAnnotation.name().equals("cquery")) {
String commandToActAs = "build"; // TODO: Work out how to pass this signal in from a flag or similar
commandForInheritance = runtime.getCommandMap().get(commandToActAs).getClass().getAnnotation(Command.class);
}
for (Class<? extends BlazeCommand> base : commandForInheritance.inherits()) {
getCommandNamesToParseHelper(base.getAnnotation(Command.class), accumulator);
}
accumulator.add(commandAnnotation.name());
} It's a special-case, but it's quite nicely localised, and I think makes a lot of sense from a "cquery acts like other commands but isn't itself them" perspective.
I personally don't care about this particular edge-case, but technically the fact that setting |
I'm disinclined to follow the cquery inherits TestCommand approach if it's still not a complete solution due to the possibility of other commands. In principle people could set directives for any command in the bazelrc, and the total number is high. Having some variation of I guess this ultimately depends on what you, as a user, expect from your CI model. I'm fuzzier on that than you are, naturally, which I think makes it harder for me to see something decisive. Can your CI model confidently state which commands it cares about where? i.e. if someone adds any of these to a bazelrc:
are you comfortable with a statically declared set of which commands matter? Even though technically it could miss relevant changes when that set is miscoded? If so, I suppose I realize the |
I think that's probably fair enough (though I also lean slightly towards not making the perfect the enemy of the good - maybe the first feature request for a conflicting inherit could be the trigger for a more complex solution like
I think it's reasonable to view If your CI system is to run arbitrary user-supplied shell-scripts, for sure all bets are off, but that doesn't mean we shouldn't provide building blocks for more constrained and controllable systems.
This is a recipe for pain, I think. Bazel's configuration language has no stability guarantees (i.e. that new constructs won't be introduced), and is already rather complex. Needing to properly parse and follow things like Bazel could perhaps offer some other building blocks here, such as a better structured
Ooh, I did not know
I think it retains exactly the same restrictions on logic?
you would need to know whether your CI is going to run |
I'll respond to your other comments further, but re:
It started out experimental but we quickly realized it's useful enough to deserve proper support. Where is it still tagged experimental? The current documentation for it is obscure, in recognition of that history. I believe it's only referenced in the docs at https://docs.bazel.build/versions/master/configurable-attributes.html#why-doesnt-my-select-choose-what-i-expect and https://docs.bazel.build/versions/master/cquery.html#configurations |
Mostly the last line of this: % bazel help config | head -n 12
[bazel release 4.1.0]
Usage: bazel config <options> [<config_id> | <config_id> <config_id>]
Displays the given configuration objects, if they can be found in the Skyframe cache. The best way
to use this command is to first run a build (or cquery), and then immediately run the config
command to view the configuration. Note that any flags passed to build (or cquery) must also be
passed to config, or else the Skyframe cache will be evicted and no configurations will be found.
If two configuration ids are passed, the difference between them will be computed and displayed,
instead of the entire configurations.
This command is experimental and unsupported. It's also not listed in https://docs.bazel.build/versions/master/command-line-reference.html#commands |
I'm sorry I'm behind on responsiveness at the moment. This is still in my inbox radar. |
(trying to converge vs. diverge the conversation): does this mean you find the If so, that sounds great in the name of minimal new complexity. If not, carry on below...
I'm just saying that The Anyway... my most important point is to consider when intrinsic new Bazel complexity is worth the cost, both in terms of adding it and considering how it might have to evolve over time. Inheriting from |
Absolutely. Let's ship it! :) |
This makes flags like `--test_arg` present in `.bazelrc` files be factored into the configuration hash for test targets. See bazelbuild#13428 for extensive context.
This makes flags like `--test_arg` present in `.bazelrc` files be factored into the configuration hash for test targets. See bazelbuild#13428 for extensive context.
This was fixed by 20aff82 |
This makes directives like `test --test_arg=foo` present in `.bazelrc` files be factored into the configuration hash for test targets. See bazelbuild#13428 for extensive context. Closes bazelbuild#13491. PiperOrigin-RevId: 382143334
This makes directives like `test --test_arg=foo` present in `.bazelrc` files be factored into the configuration hash for test targets. See bazelbuild#13428 for extensive context. Closes bazelbuild#13491. PiperOrigin-RevId: 382143334
I expect
cquery
when querying tests to reflect flags like--test_env
and--test_arg
. It appears to reflect these if they're specified on the command line, but not if they're in a .bazelrc file:Reproduction (making a clean workspace for each run, so we're definitely not seeing weird leftover state from previous runs):
cquery
does appear to correctly pay attention to.bazelrc
files for things that would affect the build actions that produce the tests, but appears to be ignored for things that would affect the test actions.What operating system are you running Bazel on?
macOS
What's the output of
bazel info release
?release 4.0.0
/cc @gregestren
The text was updated successfully, but these errors were encountered: