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

Output Runner will only run each unique command+args once #422

Merged
merged 9 commits into from
Oct 22, 2020
Merged

Output Runner will only run each unique command+args once #422

merged 9 commits into from
Oct 22, 2020

Conversation

vpanta
Copy link
Contributor

@vpanta vpanta commented Oct 7, 2020

Prospective feature that would really help us, just putting it out there as a proposal.

Goes along with #421

@vpanta vpanta requested a review from achew22 as a code owner October 7, 2020 17:51
@google-cla google-cla bot added the cla: yes label Oct 7, 2020
@achew22
Copy link
Member

achew22 commented Oct 7, 2020

This seems entirely reasonable to me! Could I have you add an e2e test to validate the behavior? Here is a preexisting output runner test that you can duplicate and extend to validate your new functionality.

Thanks so much for your contribution! This is a really good usability improvement

@vpanta
Copy link
Contributor Author

vpanta commented Oct 8, 2020

This seems entirely reasonable to me! Could I have you add an e2e test to validate the behavior? Here is a preexisting output runner test that you can duplicate and extend to validate your new functionality.

+1, not the most straightforward, but crafted a test to write words to the sentinel file based on requested commands. So we can test that each word was unique.

@achew22
Copy link
Member

achew22 commented Oct 8, 2020

+1, not the most straightforward, but crafted a test to write words to the sentinel file based on requested commands. So we can test that each word was unique.

Thanks for doing that. Out of curiosity, do these pass on your box locally?

@vpanta
Copy link
Contributor Author

vpanta commented Oct 8, 2020

+1, not the most straightforward, but crafted a test to write words to the sentinel file based on requested commands. So we can test that each word was unique.

Thanks for doing that. Out of curiosity, do these pass on your box locally?

Shoot, it's still failing on buildkite. But yeah, they pass fine when I run bazel test //e2e/output_runner/.... I have another idea which shouldn't require a sentinel file in this manner, so let me give that a shot.

@vpanta
Copy link
Contributor Author

vpanta commented Oct 8, 2020

Ok, maybe it'll work now. I'd actually been using --test_filter to just run my test locally, and it was passing. It seems the issue is that the tests aren't actually hermetic, and the main-dir doesn't get reset between them (an assumption I'd made), so when running as the full suite, the defs.bzl file actually keeps the content put into it by TestOutputRunner (print("not it")). This is likely why it was breaking with the old mechanism as well: it wasn't actually getting the signal to run any commands when executing as a suite!

While I'm sure some form of ensuring the hermeticity would be preferred, I for now just made TestOutputRunner and this new test both overwrite defs.bzl with what they expect before they act.

@achew22
Copy link
Member

achew22 commented Oct 12, 2020

While I'm sure some form of ensuring the hermeticity would be preferred, I for now just made TestOutputRunner and this new test both overwrite defs.bzl with what they expect before they act.

I believe splitting the test data into two sets of targets would provide you this flexibility and make the tests more hermetic. WDYT about that as a solution?

@achew22
Copy link
Member

achew22 commented Oct 17, 2020

Friendly ping on this

@vpanta
Copy link
Contributor Author

vpanta commented Oct 18, 2020

Hah, sorry, crazy week (moving houses + work makes me forgetful)

I'll try and wrap this up this upcoming week!

@achew22
Copy link
Member

achew22 commented Oct 18, 2020

No rush at all, just wanted to make sure I didn't scare you off 😁

@vpanta
Copy link
Contributor Author

vpanta commented Oct 20, 2020

Ok, so looking at the way TestMain works, I'd have to move some of the tests to a separate package I believe. It sets up the tests and then runs them all, and at the moment the helpers for setting up the directory are not available outside of the bazel_testing package.

So did you mean for me to fully create a separate suite?

@achew22
Copy link
Member

achew22 commented Oct 20, 2020

Ok, so looking at the way TestMain works, I'd have to move some of the tests to a separate package I believe. It sets up the tests and then runs them all, and at the moment the helpers for setting up the directory are not available outside of the bazel_testing package.

If you don't think this is possible, then please don't do it. I'd rather have the feature in. My expectation was that you could do something like this:

const mainFiles = `
-- single/defs.bzl --
def fix_deps():
  print("runacommand")
-- single/BUILD --
load("//single:defs.bzl", "fix_deps")
fix_deps()
sh_binary(
  name = "test",
  srcs = ["test.sh"],
)
sh_binary(
  name = "overwrite",
  srcs = ["overwrite.sh"],
)
-- single/test.sh --
printf "action"
-- single/overwrite.sh --
printf "overwrite"
-- multiple/defs.bzl --
def fix_deps():
  print("runacommand")
  print("runacommand")
  print("runacommand")
  print("runacommand")
-- multiple/BUILD --
load("//:defs.bzl", "fix_deps")
fix_deps()
sh_binary(
  name = "test",
  srcs = ["test.sh"],
)
sh_binary(
  name = "overwrite",
  srcs = ["overwrite.sh"],
)
-- multiple/test.sh --
printf "action"
-- multiple/overwrite.sh --
printf "overwrite"
`

Then you could target //single:test and //multiple:test in the tests. Would that work?

@vpanta
Copy link
Contributor Author

vpanta commented Oct 20, 2020

facepalm

Yes! That works fine! Honestly for a minute when you said add targets I was thinking of the actual bazel e2e test call, not the inner generated rules.

And duh, just creating a second internal package should work I think.

@vpanta
Copy link
Contributor Author

vpanta commented Oct 20, 2020

Ok, updated :D

@@ -93,6 +93,8 @@ func TestMatchRegex(t *testing.T) {
buf.WriteString("buildozer 'add deps test_dep2' //target2:target2\n")
buf.WriteString("buildifier 'cmd_nvm' //target_nvm:target_nvm\n")
buf.WriteString("not_a_match 'nvm' //target_nvm:target_nvm\n")
// Duplicate match, to be deduplicated.
buf.WriteString("buildifier 'cmd_ignore' //target_ignore:target_ignore\n")
Copy link
Member

Choose a reason for hiding this comment

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

Sorry to bring something like this up do late in the review process but I didn't realize till just now. Does this imply that a program who emits:

buildifier 'add deps test_dep1' //target
buildifier 'add deps test_dep2' //target

Would only have the first buildifier run? Wouldn't we want to dedupe based on both the command and arguments so that we don't have to do 2 builds in order to add 2 deps to a binary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This already dedupes based on command and arguments. This just looks unclear (in fact, when you raised this, I had to read back over it a few times to convince myself it's correct).

This is a buildifier call not buildozer, and the matcher for it does not use string parts in its call to buildifier below.

I've updated this with an extra string and some comments to make it clearer the diff between this line and the additional buildozer line I've added as well.

Copy link
Member

Choose a reason for hiding this comment

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

Ah! I think I see it now. buildifier != buildozer. I think this invocation of buildifier is a bit strange. Wouldn't buildifer be applied to a single file to format it? Why is it taking a cmd_ignore and a target?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

lol, copy-pasta? I was copying line 94 (as another bazel output to match on) but changing it slightly, so that it'd match the regex but not fully match the line.

I can do something else with it.

Copy link
Member

Choose a reason for hiding this comment

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

I mostly look at the test cases to see examples of how it would actually be used. My tiny monkey brain would be a little less taxed if the examples were a little more straight forward. Sorry!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

lol, np, I just updated this to match the buildozer and gazelle suggestions from documentation.

@achew22 achew22 merged commit c3bdadf into bazelbuild:master Oct 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants