-
Notifications
You must be signed in to change notification settings - Fork 182
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
diff_test: add rule and tests #136
Conversation
Generated Stardoc: diff_testdiff_test(name, file1, file2, expect_same, kwargs) A test that compares the contents of two files. The test succeeds when the files are expected to be the same (with regard to Parameters
|
All green now, ping @laurentlb |
rules/private/diff_test_private.bzl
Outdated
""" | ||
|
||
def _impl(ctx): | ||
if ctx.attr.is_windows: |
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 may be more readable to have two functions, one for Windows, one for Linux (to avoid a long if block).
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.
Done.
rules/private/diff_test_private.bzl
Outdated
was_different = "'#!/bin/sh\nexit 0'" | ||
|
||
# Run the shell command to generate 'test_script'. | ||
ctx.actions.run_shell( |
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.
The code is a bit surprising. You run the diff as part of the build, and you generate a dummy file (exit 0 / exit 1) that will be executed during the test.
Instead, you could write the shell script with actions.write_file
. Then the diff
is executed as part of the test.
(the same pattern as in https://github.com/bazelbuild/examples/blob/master/rules/test_rule/line_length.bzl)
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.
Yes, but inputs must become runfiles. Finding them is hard enough in a Bash script, it's even harder in a Batch file.
rules/private/diff_test_private.bzl
Outdated
# Contents of 'test_script' depending on diff result and expectation. | ||
if ctx.attr.expect_same: | ||
was_same = "'#!/bin/sh\nexit 0'" | ||
was_different = "\"#!/bin/sh\necho 'Expected \'$1\' and \'$2\' to be the same' >&2\nexit 1\"" |
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 can be useful for the user to print the diff
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.
Yes, with Bash that's easy (diff ... | head
) but on Windows fc.exe
is extremely chatty and there's no head
-like utility.
rules/private/diff_test_private.bzl
Outdated
attrs = { | ||
"file1": attr.label(mandatory = True, allow_single_file = True), | ||
"file2": attr.label(mandatory = True, allow_single_file = True), | ||
"expect_same": attr.bool(default = True), |
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.
Do you actually need the expect_same
attribute?
I don't see a good use-case for that. I'd suggest to keep the rule even simpler and remove it.
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.
Done.
All green, PTAL. Updated documentation: diff_testdiff_test(name, file1, file2, kwargs) A test that compares the contents of two files. The rule compares the files at build time. If the files match, the rule (The comparison is done at build time, not test time, because it makes the Parameters
|
It feels like it defeats the purpose of tests. Do we have a tracking bug? Or can you start a discussion on the mailing-list? If our recommendation is to generate files that just do |
Actually, that makes sense. Let me think it over and ping this thread later. |
This new test rule compares two files and passes if the files match. On Linux/macOS/non-Windows, the test compares files using 'diff'. On Windows, the test compares files using 'fc.exe'. This utility is available on all Windows versions I tried (Windows 2008 Server, Windows 2016 Datacenter Core). See bazelbuild/bazel#5508 See bazelbuild/bazel#4319
PTAL. Stardoc below. diff_testdiff_test(name, file1, file2, kwargs) A test that compares two files. The test succeeds if the files' contents match. Parameters
|
Hold on, I discovered a bug with |
PTAL -- all fixed, ready for review. |
ping |
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.
Looking pretty good. Just one concern.
Sorry for the review delay.
test_bin = ctx.actions.declare_file(ctx.label.name + "-test.bat") | ||
ctx.actions.write( | ||
output = test_bin, | ||
content = r"""@echo off |
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.
I find it a little awkward to have this much content written as a string literal in Starlark. Could we move it to a bat file and use that as an action input?
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.
I tried, but couldn't: I created templates under //rules/private
and added a label attribute to _diff_test
that select()
s from them:
diff_script_template = select({
"@bazel_tools//src/conditions:host_windows": "//rules/private:diff_test_tmpl.bat",
"//conditions:default": "//rules/private:diff_test_tmpl.sh",
}),
Unfortunately the rule can't find the templates when the rule itself is in an external repo.
If you don't mind, I'd leave the ugly strings here; that approach works.
I edited a test to pull the rule from an external repo.
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.
I don't understand the issue you're running into ...
- It's not necessary to select on the diff script -- you can depend on the scripts for both windows and non-windows, and only actually use the script you need based on the value of is_windows.
- Depending on a script "tool" dependency is a pretty normal pattern for rules. If there's a serious problem with adopting this pattern from this repository, we should investigate.
That said, I know this review has been going slowly, so I'm fine with proceeding as-is and following up later. It should be an easy cleanup.
test_bin = ctx.actions.declare_file(ctx.label.name + "-test.bat") | ||
ctx.actions.write( | ||
output = test_bin, | ||
content = r"""@echo off |
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.
I don't understand the issue you're running into ...
- It's not necessary to select on the diff script -- you can depend on the scripts for both windows and non-windows, and only actually use the script you need based on the value of is_windows.
- Depending on a script "tool" dependency is a pretty normal pattern for rules. If there's a serious problem with adopting this pattern from this repository, we should investigate.
That said, I know this review has been going slowly, so I'm fine with proceeding as-is and following up later. It should be an easy cleanup.
Thank you @c-parsons ! |
Well, this is embarrassing -- I found a simpler solution to the problem I meant to solve with diff_test. |
Is the solution generalized to make diff_test entirely obsolete? (Care to elaborate?) |
No, it's specialized: bazelbuild/buildtools#610 diff_test is generic, but I had no purpose for it other than fixing Using diff_test in Buildtools would require either to depend on Skylib as an external repo, or to copy diff_test.bzl into Buildtools. Buildtools already depends transitively on an older Skylib version, updating the dependencies might break the affected projects. And copying diff_test into Buildtools repo risks diverging from the version in Skylib. All in all, fixing Buildtools without diff_test is easier, but now I have no users for diff_test. It's a nice-to-have rule, but we shouldn't maintain it until we actually need it. If I delete it now, we can revive it if we need so. WDYT? |
diff_test fits a pattern which is used in many places... For one, I was hoping to use it for Stardoc's tests instead of a home-grown diff test shell script Hopefully that would be sufficient to justify the maintenance of diff_test ? As a side note, I would encourage you to upgrade other repositories to the newest version of skylib :) |
Yes, that's enough reason to keep the test. Yay! |
This PR adds a new rule: diff_test().
The test rule compares the contents of two files.
The 'diff_test.expect_same' attribute tells
whether the files are expected to be the same or
not.
The test succeeds if the files are the same and
expected to be so, or if the files are different
and expected to be so. Otherwise the test fails.
This rules requires no Bash on Windows, so it
works without Bash, without /usr/bin/diff, and
with the Windows-native test wrapper.
See bazelbuild/bazel#5508
See bazelbuild/bazel#4319