-
Notifications
You must be signed in to change notification settings - Fork 430
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
Rust test targets now create a test launcher allow for setting env vars #579
Conversation
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.
This looks useful, and I'm surprisingly OK with it given it's generating compilable rust code in starlark :D I'm a little worried about not escaping quotes in values, so I'd lean towards using something like:
"r#####\"{}\"#####"
in the templates rather than
"\"{}\""
I'd definitely like others' opinions before merging, though, as this is a significant change, and there are potentially a lot of edge cases :)
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.
Works for me, but again, would want to hear from others before merging :)
I kept thinking and chatting with people about this yesterday. The Bazel team said they would accept a contribution to allow specifying Second avenue is to not use a rules_rust provided testrunner, but to bake custom one only for the tests that need to have env vars set, only in the project that has the affected tests. It doesn't even have to be a template, the test runner can assume a data file at some well specified location. Third is the approach of this PR, to have a general Rust test runner that is used for all Rust tests built with rules_rust. As with the second point it doesn't necessarily have to be a template, we can use data files instead. This approach has a potential/handwave-handwave advantage that once we want to produce junit xml test outputs which Bazel can parse and report nicer test results, we will have to have the test runner anyway. The downside is a bit of complexity and my paranoid fear of misusing the test runner for other stuff. Andre, Daniel, what do you think about this? |
I don't think users should have to bake environment variables into their tests and it appears that most user's expect to be able to do something like in this PR (as per a recent slack thread). I think for the first and third options, they're more or less invisible to the user. They'll want to set an |
This sounds long-term ideal.
This sounds not particularly worth the complexity, particularly if in the long term we're either going to delete the test runner, or run everything under it anyway (for e.g. junit XML).
Seems reasonable in the short term, and long-term we can either delete it, or build it up more. |
After looking into ways how to make debugging work I yield :) Let's do this. I propose a different approach that I think will result in simpler code:
I think it's worth doing this because:
What do you think? |
Sounds good! |
@hlopko @illicitonion How's something like this look? |
@@ -219,6 +219,100 @@ def _rust_binary_impl(ctx): | |||
), | |||
) | |||
|
|||
def _create_test_launcher(ctx, toolchain, output, providers): |
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 we need to do all of this? What I had in mind was to add this into rust_test rule declaration:
"_process_wrapper": attr.label(
default = Label("//util/test_runner"),
executable = True,
allow_single_file = True,
cfg = "exec",
),
And then:
0) add a rust_binary at //util/test_runner:test_runner
- in rust_test access the runner using
ctx.executable._test_runner
- put that in the DefaultInfo that rust_test provides
- register action that writes list of env variables into a file
- put that file into DefaultInfo runfiles
- register action that symlinks the actual test binary into some path
- put both the test and the symlink into runfiles
- modify test_runner to look into runfiles for env-vars file and for the symlink
Does it make sense?
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.
This is different from the process wrapper because the process wrapper is used as an executable for an action. However, the launcher/test_runner needs to be the executable returned by the rule so it gets executed when you bazel test //:my_target
. Bazel will otherwise throw an error if you return an executable that is not created by an action of that rule. Is there another way around this? Aside from having to create the binary in an action in the rule, I what you've written is more or less what I'm doing, right?
and ensuring the variables are set for the underlying test executable. | ||
"""), | ||
), | ||
"_launcher_installer": attr.label( |
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 think the rust_binary will deal with the extension automatically, so you won't need the installer
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 installer is just a script that helps us create the test runner/launcher in an action in the test rule. I made this target so I can use a batch file on windows and not require the use of bash
.
Also, I changed the |
rust/private/rust.bzl
Outdated
# TODO: Find a better way to detect the configuration this executable | ||
# was built in. Here we detect whether or not the executable is built | ||
# for windows based on it's extension. | ||
if ctx.executable._launcher.basename.endswith(".exe"): |
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.
There's a toolchain.os
property I think you could use? The toolchain should be in the right configuration?
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 wasn't sure if the toolchain would always match the configuration of launcher
but I think in most cases it's safe to use the toolchain. Updated
Co-authored-by: Daniel Wagner-Hall <dawagner@gmail.com>
Co-authored-by: Daniel Wagner-Hall <dawagner@gmail.com>
In #579 I had intended to take advantage of the same behavior `cargo_build_script` was for `expand_location` but forgot to implement the counterpart in the `launcher` target. This fixes that and updates tests to check this behavior.
I was mistaken when I originally implemented #577 because I didn't realize that std::env loaded environment variables at compile time. The goal of this PR was to define environment variables at runtime. This appeared to be more complicated than I had thought. It seems there needs to be a launcher/runner that is produced by your rule and invokes your test executable to be able to guarantee the environment is configured for the test.
This PR creates a small shell script that wraps
rust_test
targets to enable the use of theenv
attribute at runtime.